All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/14] skylake display scalers
@ 2015-04-07 22:28 Chandra Konduru
  2015-04-07 22:28 ` [PATCH 01/14] drm: Adding drm helper function drm_plane_from_index() Chandra Konduru
                   ` (15 more replies)
  0 siblings, 16 replies; 54+ messages in thread
From: Chandra Konduru @ 2015-04-07 22:28 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira, daniel.vetter

Primary changes in this version are:
1) Moved num_scalers to crtc
2) Changed src/dst rect ranges to #defines
3) Dropped scaling ratios from state instead calculating when needed
4) Dropped filter from scaler
5) Squashed helper functions from standalone patches into patch where 1st used
6) Kept sprite src tect in 16.16 format

Though changes are minor but they got sprinkled into multiple patches.

Sending full patch series for completeness. Individual patch headers
have additional details on changes. This series should cleanly
merge to latest drm-intel-nighly.

Chandra Konduru (14):
  drm: Adding drm helper function drm_plane_from_index().
  drm/i915: Register definitions for skylake scalers
  drm/i915: skylake scaler structure definitions
  drm/i915: Initialize plane colorkey to NONE
  drm/i915: Initialize skylake scalers
  drm/i915: Keep sprite plane src rect in 16.16 format
  drm/i915: Dump scaler_state too as part of dumping crtc_state
  drm/i915: Preserve scaler state when clearing crtc_state
  drm/i915: setup scalers for crtc_compute_config
  drm/i915: Ensure setting up scalers into staged crtc_state
  drm/i915: copy staged scaler state from drm state to crtc->config.
  drm/i915: skylake panel fitting using shared scalers
  drm/i915: skylake primary plane scaling using shared scalers
  drm/i915: skylake sprite plane scaling using shared scalers

 drivers/gpu/drm/drm_crtc.c           |   22 ++
 drivers/gpu/drm/i915/i915_reg.h      |  115 +++++++++
 drivers/gpu/drm/i915/intel_atomic.c  |  163 +++++++++++++
 drivers/gpu/drm/i915/intel_display.c |  441 +++++++++++++++++++++++++++++++---
 drivers/gpu/drm/i915/intel_dp.c      |    8 +
 drivers/gpu/drm/i915/intel_drv.h     |   76 ++++++
 drivers/gpu/drm/i915/intel_sprite.c  |   83 +++++--
 include/drm/drm_crtc.h               |    1 +
 8 files changed, 855 insertions(+), 54 deletions(-)

-- 
1.7.9.5

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

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

* [PATCH 01/14] drm: Adding drm helper function drm_plane_from_index().
  2015-04-07 22:28 [PATCH 00/14] skylake display scalers Chandra Konduru
@ 2015-04-07 22:28 ` Chandra Konduru
  2015-04-10  0:36   ` Chandra Konduru
  2015-04-07 22:28 ` [PATCH 02/14] drm/i915: Register definitions for skylake scalers Chandra Konduru
                   ` (14 subsequent siblings)
  15 siblings, 1 reply; 54+ messages in thread
From: Chandra Konduru @ 2015-04-07 22:28 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira, daniel.vetter, dri-devel

Adding drm helper function to return plane pointer from index where
index is a returned by drm_plane_index.

v2:
-avoided nested loop by adding loop count (Daniel)

v3:
-updated patch header prefix to 'drm' (Matt)

Cc: dri-devel@lists.freedesktop.org

Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
---
 drivers/gpu/drm/drm_crtc.c |   22 ++++++++++++++++++++++
 include/drm/drm_crtc.h     |    1 +
 2 files changed, 23 insertions(+)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index d576a4d..0f0159b 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1289,6 +1289,28 @@ unsigned int drm_plane_index(struct drm_plane *plane)
 EXPORT_SYMBOL(drm_plane_index);
 
 /**
+ * drm_plane_from_index - find the registered plane at an index
+ * @idx: index of registered plane to find for
+ *
+ * Given a plane index, return the registered plane from DRM device's
+ * list of planes with matching index.
+ */
+struct drm_plane *
+drm_plane_from_index(struct drm_device *dev, int idx)
+{
+	struct drm_plane *plane;
+	unsigned int i = 0;
+
+	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+		if (i == idx)
+			return plane;
+		i++;
+	}
+	return NULL;
+}
+EXPORT_SYMBOL(drm_plane_from_index);
+
+/**
  * drm_plane_force_disable - Forcibly disable a plane
  * @plane: plane to disable
  *
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 7b5c661..6b30036 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1264,6 +1264,7 @@ extern int drm_plane_init(struct drm_device *dev,
 			  bool is_primary);
 extern void drm_plane_cleanup(struct drm_plane *plane);
 extern unsigned int drm_plane_index(struct drm_plane *plane);
+extern struct drm_plane * drm_plane_from_index(struct drm_device *dev, int idx);
 extern void drm_plane_force_disable(struct drm_plane *plane);
 extern int drm_plane_check_pixel_format(const struct drm_plane *plane,
 					u32 format);
-- 
1.7.9.5

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

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

* [PATCH 02/14] drm/i915: Register definitions for skylake scalers
  2015-04-07 22:28 [PATCH 00/14] skylake display scalers Chandra Konduru
  2015-04-07 22:28 ` [PATCH 01/14] drm: Adding drm helper function drm_plane_from_index() Chandra Konduru
@ 2015-04-07 22:28 ` Chandra Konduru
  2015-04-07 22:28 ` [PATCH 03/14] drm/i915: skylake scaler structure definitions Chandra Konduru
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 54+ messages in thread
From: Chandra Konduru @ 2015-04-07 22:28 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira, daniel.vetter

Adding register definitions for skylake scalers.
v2:
-add #define for plane selection mask (me)

Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h |  115 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 115 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index b134fa3..6ad1932 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -5096,6 +5096,121 @@ enum skl_disp_power_wells {
 #define PS_WIN_SZ(pipe)		_PIPE(pipe, _PSA_WIN_SZ, _PSB_WIN_SZ)
 #define PS_WIN_POS(pipe)	_PIPE(pipe, _PSA_WIN_POS, _PSB_WIN_POS)
 
+/*
+ * Skylake scalers
+ */
+#define _PS_1A_CTRL      0x68180
+#define _PS_2A_CTRL      0x68280
+#define _PS_1B_CTRL      0x68980
+#define _PS_2B_CTRL      0x68A80
+#define _PS_1C_CTRL      0x69180
+#define PS_SCALER_EN        (1 << 31)
+#define PS_SCALER_MODE_MASK (3 << 28)
+#define PS_SCALER_MODE_DYN  (0 << 28)
+#define PS_SCALER_MODE_HQ  (1 << 28)
+#define PS_PLANE_SEL_MASK  (7 << 25)
+#define PS_PLANE_SEL(plane) ((plane + 1) << 25)
+#define PS_FILTER_MASK         (3 << 23)
+#define PS_FILTER_MEDIUM       (0 << 23)
+#define PS_FILTER_EDGE_ENHANCE (2 << 23)
+#define PS_FILTER_BILINEAR     (3 << 23)
+#define PS_VERT3TAP            (1 << 21)
+#define PS_VERT_INT_INVERT_FIELD1 (0 << 20)
+#define PS_VERT_INT_INVERT_FIELD0 (1 << 20)
+#define PS_PWRUP_PROGRESS         (1 << 17)
+#define PS_V_FILTER_BYPASS        (1 << 8)
+#define PS_VADAPT_EN              (1 << 7)
+#define PS_VADAPT_MODE_MASK        (3 << 5)
+#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_PWR_GATE_1A     0x68160
+#define _PS_PWR_GATE_2A     0x68260
+#define _PS_PWR_GATE_1B     0x68960
+#define _PS_PWR_GATE_2B     0x68A60
+#define _PS_PWR_GATE_1C     0x69160
+#define PS_PWR_GATE_DIS_OVERRIDE       (1 << 31)
+#define PS_PWR_GATE_SETTLING_TIME_32   (0 << 3)
+#define PS_PWR_GATE_SETTLING_TIME_64   (1 << 3)
+#define PS_PWR_GATE_SETTLING_TIME_96   (2 << 3)
+#define PS_PWR_GATE_SETTLING_TIME_128  (3 << 3)
+#define PS_PWR_GATE_SLPEN_8             0
+#define PS_PWR_GATE_SLPEN_16            1
+#define PS_PWR_GATE_SLPEN_24            2
+#define PS_PWR_GATE_SLPEN_32            3
+
+#define _PS_WIN_POS_1A      0x68170
+#define _PS_WIN_POS_2A      0x68270
+#define _PS_WIN_POS_1B      0x68970
+#define _PS_WIN_POS_2B      0x68A70
+#define _PS_WIN_POS_1C      0x69170
+
+#define _PS_WIN_SZ_1A       0x68174
+#define _PS_WIN_SZ_2A       0x68274
+#define _PS_WIN_SZ_1B       0x68974
+#define _PS_WIN_SZ_2B       0x68A74
+#define _PS_WIN_SZ_1C       0x69174
+
+#define _PS_VSCALE_1A       0x68184
+#define _PS_VSCALE_2A       0x68284
+#define _PS_VSCALE_1B       0x68984
+#define _PS_VSCALE_2B       0x68A84
+#define _PS_VSCALE_1C       0x69184
+
+#define _PS_HSCALE_1A       0x68190
+#define _PS_HSCALE_2A       0x68290
+#define _PS_HSCALE_1B       0x68990
+#define _PS_HSCALE_2B       0x68A90
+#define _PS_HSCALE_1C       0x69190
+
+#define _PS_VPHASE_1A       0x68188
+#define _PS_VPHASE_2A       0x68288
+#define _PS_VPHASE_1B       0x68988
+#define _PS_VPHASE_2B       0x68A88
+#define _PS_VPHASE_1C       0x69188
+
+#define _PS_HPHASE_1A       0x68194
+#define _PS_HPHASE_2A       0x68294
+#define _PS_HPHASE_1B       0x68994
+#define _PS_HPHASE_2B       0x68A94
+#define _PS_HPHASE_1C       0x69194
+
+#define _PS_ECC_STAT_1A     0x681D0
+#define _PS_ECC_STAT_2A     0x682D0
+#define _PS_ECC_STAT_1B     0x689D0
+#define _PS_ECC_STAT_2B     0x68AD0
+#define _PS_ECC_STAT_1C     0x691D0
+
+#define _ID(id, a, b) ((a) + (id)*((b)-(a)))
+#define SKL_PS_CTRL(pipe, id) _PIPE(pipe,        \
+			_ID(id, _PS_1A_CTRL, _PS_2A_CTRL),       \
+			_ID(id, _PS_1B_CTRL, _PS_2B_CTRL))
+#define SKL_PS_PWR_GATE(pipe, id) _PIPE(pipe,    \
+			_ID(id, _PS_PWR_GATE_1A, _PS_PWR_GATE_2A), \
+			_ID(id, _PS_PWR_GATE_1B, _PS_PWR_GATE_2B))
+#define SKL_PS_WIN_POS(pipe, id) _PIPE(pipe,     \
+			_ID(id, _PS_WIN_POS_1A, _PS_WIN_POS_2A), \
+			_ID(id, _PS_WIN_POS_1B, _PS_WIN_POS_2B))
+#define SKL_PS_WIN_SZ(pipe, id)  _PIPE(pipe,     \
+			_ID(id, _PS_WIN_SZ_1A, _PS_WIN_SZ_2A),   \
+			_ID(id, _PS_WIN_SZ_1B, _PS_WIN_SZ_2B))
+#define SKL_PS_VSCALE(pipe, id)  _PIPE(pipe,     \
+			_ID(id, _PS_VSCALE_1A, _PS_VSCALE_2A),   \
+			_ID(id, _PS_VSCALE_1B, _PS_VSCALE_2B))
+#define SKL_PS_HSCALE(pipe, id)  _PIPE(pipe,     \
+			_ID(id, _PS_HSCALE_1A, _PS_HSCALE_2A),   \
+			_ID(id, _PS_HSCALE_1B, _PS_HSCALE_2B))
+#define SKL_PS_VPHASE(pipe, id)  _PIPE(pipe,     \
+			_ID(id, _PS_VPHASE_1A, _PS_VPHASE_2A),   \
+			_ID(id, _PS_VPHASE_1B, _PS_VPHASE_2B))
+#define SKL_PS_HPHASE(pipe, id)  _PIPE(pipe,     \
+			_ID(id, _PS_HPHASE_1A, _PS_HPHASE_2A),   \
+			_ID(id, _PS_HPHASE_1B, _PS_HPHASE_2B))
+#define SKL_PS_ECC_STAT(pipe, id)  _PIPE(pipe,     \
+			_ID(id, _PS_ECC_STAT_1A, _PS_ECC_STAT_2A),   \
+			_ID(id, _PS_ECC_STAT_1B, _PS_ECC_STAT_2B)
+
 /* legacy palette */
 #define _LGC_PALETTE_A           0x4a000
 #define _LGC_PALETTE_B           0x4a800
-- 
1.7.9.5

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

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

* [PATCH 03/14] drm/i915: skylake scaler structure definitions
  2015-04-07 22:28 [PATCH 00/14] skylake display scalers Chandra Konduru
  2015-04-07 22:28 ` [PATCH 01/14] drm: Adding drm helper function drm_plane_from_index() Chandra Konduru
  2015-04-07 22:28 ` [PATCH 02/14] drm/i915: Register definitions for skylake scalers Chandra Konduru
@ 2015-04-07 22:28 ` Chandra Konduru
  2015-04-07 22:28 ` [PATCH 04/14] drm/i915: Initialize plane colorkey to NONE Chandra Konduru
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 54+ messages in thread
From: Chandra Konduru @ 2015-04-07 22:28 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira, daniel.vetter

skylake scaler structure definitions. scalers live in crtc_state as
they are pipe resources. They can be used either as plane scaler or
panel fitter.

scaler assigned to either plane (for plane scaling) or crtc (for panel
fitting) is saved in scaler_id in plane_state or crtc_state respectively.

scaler_id is used instead of scaler pointer in plane or crtc state
to avoid updating scaler pointer everytime a new crtc_state is created.

v2:
-made single copy of min/max values for scalers (Matt)

v3:
-updated commentary for scaler_id (me)

v4:
-converted src/dst ranges to #defines, dropped ratios (Matt)

Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
---
 drivers/gpu/drm/i915/intel_drv.h |   68 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 4799b11..adca692 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -256,6 +256,26 @@ struct intel_plane_state {
 	 * enable/disable the primary plane
 	 */
 	bool hides_primary;
+
+	/*
+	 * scaler_id
+	 *    = -1 : not using a scaler
+	 *    >=  0 : using a scalers
+	 *
+	 * plane requiring a scaler:
+	 *   - During check_plane, its bit is set in
+	 *     crtc_state->scaler_state.scaler_users by calling helper function
+	 *     update_scaler_users.
+	 *   - scaler_id indicates the scaler it got assigned.
+	 *
+	 * plane doesn't require a scaler:
+	 *   - this can happen when scaling is no more required or plane simply
+	 *     got disabled.
+	 *   - During check_plane, corresponding bit is reset in
+	 *     crtc_state->scaler_state.scaler_users by calling helper function
+	 *     update_scaler_users.
+	 */
+	int scaler_id;
 };
 
 struct intel_initial_plane_config {
@@ -265,6 +285,49 @@ struct intel_initial_plane_config {
 	u32 base;
 };
 
+#define SKL_MIN_SRC_W 8
+#define SKL_MAX_SRC_W 4096
+#define SKL_MIN_SRC_H 8
+#define SKL_MAX_SRC_H 2304
+#define SKL_MIN_DST_W 8
+#define SKL_MAX_DST_W 4096
+#define SKL_MIN_DST_H 8
+#define SKL_MAX_DST_H 2304
+
+struct intel_scaler {
+	int id;
+	int in_use;
+	uint32_t mode;
+};
+
+struct intel_crtc_scaler_state {
+#define SKL_NUM_SCALERS 2
+	struct intel_scaler scalers[SKL_NUM_SCALERS];
+
+	/*
+	 * scaler_users: keeps track of users requesting scalers on this crtc.
+	 *
+	 *     If a bit is set, a user is using a scaler.
+	 *     Here user can be a plane or crtc as defined below:
+	 *       bits 0-30 - plane (bit position is index from drm_plane_index)
+	 *       bit 31    - crtc
+	 *
+	 * Instead of creating a new index to cover planes and crtc, using
+	 * existing drm_plane_index for planes which is well less than 31
+	 * planes and bit 31 for crtc. This should be fine to cover all
+	 * our platforms.
+	 *
+	 * intel_atomic_setup_scalers will setup available scalers to users
+	 * requesting scalers. It will gracefully fail if request exceeds
+	 * avilability.
+	 */
+#define SKL_CRTC_INDEX 31
+	unsigned scaler_users;
+
+	/* scaler used by crtc for panel fitting purpose */
+	int scaler_id;
+};
+
 struct intel_crtc_state {
 	struct drm_crtc_state base;
 
@@ -391,6 +454,8 @@ struct intel_crtc_state {
 
 	bool dp_encoder_is_mst;
 	int pbn;
+
+	struct intel_crtc_scaler_state scaler_state;
 };
 
 struct intel_pipe_wm {
@@ -493,6 +558,9 @@ struct intel_crtc {
 	struct intel_mmio_flip mmio_flip;
 
 	struct intel_crtc_atomic_commit atomic;
+
+	/* scalers available on this crtc */
+	int num_scalers;
 };
 
 struct intel_plane_wm_parameters {
-- 
1.7.9.5

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

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

* [PATCH 04/14] drm/i915: Initialize plane colorkey to NONE
  2015-04-07 22:28 [PATCH 00/14] skylake display scalers Chandra Konduru
                   ` (2 preceding siblings ...)
  2015-04-07 22:28 ` [PATCH 03/14] drm/i915: skylake scaler structure definitions Chandra Konduru
@ 2015-04-07 22:28 ` Chandra Konduru
  2015-04-07 22:28 ` [PATCH 05/14] drm/i915: Initialize skylake scalers Chandra Konduru
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 54+ messages in thread
From: Chandra Konduru @ 2015-04-07 22:28 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira, daniel.vetter

This patch initializes plane colorkey to NONE.

Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |    1 +
 drivers/gpu/drm/i915/intel_sprite.c  |    1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9c65120..f6ff02d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12773,6 +12773,7 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
 	primary->plane = pipe;
 	primary->check_plane = intel_check_primary_plane;
 	primary->commit_plane = intel_commit_primary_plane;
+	primary->ckey.flags = I915_SET_COLORKEY_NONE;
 	if (HAS_FBC(dev) && INTEL_INFO(dev)->gen < 4)
 		primary->plane = !pipe;
 
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index e9ff6fc..66b424b 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -1276,6 +1276,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
 	intel_plane->plane = plane;
 	intel_plane->check_plane = intel_check_sprite_plane;
 	intel_plane->commit_plane = intel_commit_sprite_plane;
+	intel_plane->ckey.flags = I915_SET_COLORKEY_NONE;
 	possible_crtcs = (1 << pipe);
 	ret = drm_universal_plane_init(dev, &intel_plane->base, possible_crtcs,
 				       &intel_plane_funcs,
-- 
1.7.9.5

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

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

* [PATCH 05/14] drm/i915: Initialize skylake scalers
  2015-04-07 22:28 [PATCH 00/14] skylake display scalers Chandra Konduru
                   ` (3 preceding siblings ...)
  2015-04-07 22:28 ` [PATCH 04/14] drm/i915: Initialize plane colorkey to NONE Chandra Konduru
@ 2015-04-07 22:28 ` Chandra Konduru
  2015-04-07 22:28 ` [PATCH 06/14] drm/i915: Keep sprite plane src rect in 16.16 format Chandra Konduru
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 54+ messages in thread
From: Chandra Konduru @ 2015-04-07 22:28 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira, daniel.vetter

Initializing scalers with supported values during crtc init.

v2:
-initialize single copy of min/max values (Matt)

v3:
-moved gen check to callsite (Matt)

v4:
-squashed planes begin with no scaler to here (me)

v5:
-updated init function with updated scaler state structure (Matt)

Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |   32 ++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_sprite.c  |    1 +
 2 files changed, 33 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f6ff02d..9129501 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -103,6 +103,8 @@ static void chv_prepare_pll(struct intel_crtc *crtc,
 			    const struct intel_crtc_state *pipe_config);
 static void intel_begin_crtc_commit(struct drm_crtc *crtc);
 static void intel_finish_crtc_commit(struct drm_crtc *crtc);
+static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_crtc,
+	struct intel_crtc_state *crtc_state);
 
 static struct intel_encoder *intel_find_encoder(struct intel_connector *connector, int pipe)
 {
@@ -12769,6 +12771,7 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
 
 	primary->can_scale = false;
 	primary->max_downscale = 1;
+	state->scaler_id = -1;
 	primary->pipe = pipe;
 	primary->plane = pipe;
 	primary->check_plane = intel_check_primary_plane;
@@ -12924,6 +12927,7 @@ static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev,
 	cursor->max_downscale = 1;
 	cursor->pipe = pipe;
 	cursor->plane = pipe;
+	state->scaler_id = -1;
 	cursor->check_plane = intel_check_cursor_plane;
 	cursor->commit_plane = intel_commit_cursor_plane;
 
@@ -12950,6 +12954,24 @@ static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev,
 	return &cursor->base;
 }
 
+static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_crtc,
+	struct intel_crtc_state *crtc_state)
+{
+	int i;
+	struct intel_scaler *intel_scaler;
+	struct intel_crtc_scaler_state *scaler_state = &crtc_state->scaler_state;
+
+	for (i = 0; i < intel_crtc->num_scalers; i++) {
+		intel_scaler = &scaler_state->scalers[i];
+		intel_scaler->in_use = 0;
+		intel_scaler->id = i;
+
+		intel_scaler->mode = PS_SCALER_MODE_DYN;
+	}
+
+	scaler_state->scaler_id = -1;
+}
+
 static void intel_crtc_init(struct drm_device *dev, int pipe)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -12969,6 +12991,16 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
 	intel_crtc_set_state(intel_crtc, crtc_state);
 	crtc_state->base.crtc = &intel_crtc->base;
 
+	/* initialize shared scalers */
+	if (INTEL_INFO(dev)->gen >= 9) {
+		if (pipe == PIPE_C)
+			intel_crtc->num_scalers = 1;
+		else
+			intel_crtc->num_scalers = SKL_NUM_SCALERS;
+
+		skl_init_scalers(dev, intel_crtc, crtc_state);
+	}
+
 	primary = intel_primary_plane_create(dev, pipe);
 	if (!primary)
 		goto fail;
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 66b424b..ac4aa68 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -1263,6 +1263,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
 		intel_plane->max_downscale = 1;
 		intel_plane->update_plane = skl_update_plane;
 		intel_plane->disable_plane = skl_disable_plane;
+		state->scaler_id = -1;
 
 		plane_formats = skl_plane_formats;
 		num_plane_formats = ARRAY_SIZE(skl_plane_formats);
-- 
1.7.9.5

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

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

* [PATCH 06/14] drm/i915: Keep sprite plane src rect in 16.16 format
  2015-04-07 22:28 [PATCH 00/14] skylake display scalers Chandra Konduru
                   ` (4 preceding siblings ...)
  2015-04-07 22:28 ` [PATCH 05/14] drm/i915: Initialize skylake scalers Chandra Konduru
@ 2015-04-07 22:28 ` Chandra Konduru
  2015-04-09 21:50   ` Matt Roper
  2015-04-09 23:41   ` Chandra Konduru
  2015-04-07 22:28 ` [PATCH 07/14] drm/i915: Dump scaler_state too as part of dumping crtc_state Chandra Konduru
                   ` (9 subsequent siblings)
  15 siblings, 2 replies; 54+ messages in thread
From: Chandra Konduru @ 2015-04-07 22:28 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira, daniel.vetter

This patch keeps intel_plane_state->src rect back
into 16.16 format.

v2:
-sprite src rect to match primary format (Matt, Daniel)

Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
---
 drivers/gpu/drm/i915/intel_sprite.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index ac4aa68..c05fb36 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -1006,10 +1006,10 @@ intel_check_sprite_plane(struct drm_plane *plane,
 	}
 
 	if (state->visible) {
-		src->x1 = src_x;
-		src->x2 = src_x + src_w;
-		src->y1 = src_y;
-		src->y2 = src_y + src_h;
+		src->x1 = src_x << 16;
+		src->x2 = (src_x + src_w) << 16;
+		src->y1 = src_y << 16;
+		src->y2 = (src_y + src_h) << 16;
 	}
 
 	dst->x1 = crtc_x;
-- 
1.7.9.5

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

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

* [PATCH 07/14] drm/i915: Dump scaler_state too as part of dumping crtc_state
  2015-04-07 22:28 [PATCH 00/14] skylake display scalers Chandra Konduru
                   ` (5 preceding siblings ...)
  2015-04-07 22:28 ` [PATCH 06/14] drm/i915: Keep sprite plane src rect in 16.16 format Chandra Konduru
@ 2015-04-07 22:28 ` Chandra Konduru
  2015-04-07 22:28 ` [PATCH 08/14] drm/i915: Preserve scaler state when clearing crtc_state Chandra Konduru
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 54+ messages in thread
From: Chandra Konduru @ 2015-04-07 22:28 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira, daniel.vetter

Dumps scaler state as part of dumping crtc_state.

v2:
-use regular ints from plane_state->src (me)

v3:
-changes to align with updated scaler structures (Matt)
-interpret plane_state->src as 16.16 format (Matt, Daniel)

Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |   47 ++++++++++++++++++++++++++++++++--
 1 file changed, 45 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9129501..141774e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10558,8 +10558,14 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
 				   struct intel_crtc_state *pipe_config,
 				   const char *context)
 {
-	DRM_DEBUG_KMS("[CRTC:%d]%s config for pipe %c\n", crtc->base.base.id,
-		      context, pipe_name(crtc->pipe));
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_plane *plane;
+	struct intel_plane *intel_plane;
+	struct intel_plane_state *state;
+	struct drm_framebuffer *fb;
+
+	DRM_DEBUG_KMS("[CRTC:%d]%s config %p for pipe %c\n", crtc->base.base.id,
+		      context, pipe_config, pipe_name(crtc->pipe));
 
 	DRM_DEBUG_KMS("cpu_transcoder: %c\n", transcoder_name(pipe_config->cpu_transcoder));
 	DRM_DEBUG_KMS("pipe bpp: %i, dithering: %i\n",
@@ -10596,6 +10602,9 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
 	DRM_DEBUG_KMS("port clock: %d\n", pipe_config->port_clock);
 	DRM_DEBUG_KMS("pipe src size: %dx%d\n",
 		      pipe_config->pipe_src_w, pipe_config->pipe_src_h);
+	DRM_DEBUG_KMS("num_scalers: %d\n", crtc->num_scalers);
+	DRM_DEBUG_KMS("scaler_users: 0x%x\n", pipe_config->scaler_state.scaler_users);
+	DRM_DEBUG_KMS("scaler id: %d\n", pipe_config->scaler_state.scaler_id);
 	DRM_DEBUG_KMS("gmch pfit: control: 0x%08x, ratios: 0x%08x, lvds border: 0x%08x\n",
 		      pipe_config->gmch_pfit.control,
 		      pipe_config->gmch_pfit.pgm_ratios,
@@ -10606,6 +10615,40 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
 		      pipe_config->pch_pfit.enabled ? "enabled" : "disabled");
 	DRM_DEBUG_KMS("ips: %i\n", pipe_config->ips_enabled);
 	DRM_DEBUG_KMS("double wide: %i\n", pipe_config->double_wide);
+
+	DRM_DEBUG_KMS("planes on this crtc\n");
+	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+		intel_plane = to_intel_plane(plane);
+		if (intel_plane->pipe != crtc->pipe)
+			continue;
+
+		state = to_intel_plane_state(plane->state);
+		fb = state->base.fb;
+		if (!fb) {
+			DRM_DEBUG_KMS("%s PLANE:%d plane: %u.%u idx: %d "
+				"disabled, scaler_id = %d\n",
+				plane->type == DRM_PLANE_TYPE_CURSOR ? "CURSOR" : "STANDARD",
+				plane->base.id, intel_plane->pipe,
+				(crtc->base.primary == plane) ? 0 : intel_plane->plane + 1,
+				drm_plane_index(plane), state->scaler_id);
+			continue;
+		}
+
+		DRM_DEBUG_KMS("%s PLANE:%d plane: %u.%u idx: %d enabled",
+			plane->type == DRM_PLANE_TYPE_CURSOR ? "CURSOR" : "STANDARD",
+			plane->base.id, intel_plane->pipe,
+			crtc->base.primary == plane ? 0 : intel_plane->plane + 1,
+			drm_plane_index(plane));
+		DRM_DEBUG_KMS("\tFB:%d, fb = %ux%u format = 0x%x",
+			fb->base.id, fb->width, fb->height, fb->pixel_format);
+		DRM_DEBUG_KMS("\tscaler:%d src (%u, %u) %ux%u dst (%u, %u) %ux%u\n",
+			state->scaler_id,
+			state->src.x1 >> 16, state->src.y1 >> 16,
+			drm_rect_width(&state->src) >> 16,
+			drm_rect_height(&state->src) >> 16,
+			state->dst.x1, state->dst.y1,
+			drm_rect_width(&state->dst), drm_rect_height(&state->dst));
+	}
 }
 
 static bool encoders_cloneable(const struct intel_encoder *a,
-- 
1.7.9.5

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

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

* [PATCH 08/14] drm/i915: Preserve scaler state when clearing crtc_state
  2015-04-07 22:28 [PATCH 00/14] skylake display scalers Chandra Konduru
                   ` (6 preceding siblings ...)
  2015-04-07 22:28 ` [PATCH 07/14] drm/i915: Dump scaler_state too as part of dumping crtc_state Chandra Konduru
@ 2015-04-07 22:28 ` Chandra Konduru
  2015-04-07 22:28 ` [PATCH 09/14] drm/i915: setup scalers for crtc_compute_config Chandra Konduru
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 54+ messages in thread
From: Chandra Konduru @ 2015-04-07 22:28 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira, daniel.vetter

crtc_state is cleared during mode set which wipes out complete
scaler state too. This is causing issues. To fix, ensure scaler
state is preserved because it contains not only crtc
scaler usage, but also planes using scalers on this crtc.

Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 141774e..f1051f0 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10737,11 +10737,14 @@ static void
 clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
 {
 	struct drm_crtc_state tmp_state;
+	struct intel_crtc_scaler_state scaler_state;
 
-	/* Clear only the intel specific part of the crtc state */
+	/* Clear only the intel specific part of the crtc state excluding scalers */
 	tmp_state = crtc_state->base;
+	scaler_state = crtc_state->scaler_state;
 	memset(crtc_state, 0, sizeof *crtc_state);
 	crtc_state->base = tmp_state;
+	crtc_state->scaler_state = scaler_state;
 }
 
 static struct intel_crtc_state *
-- 
1.7.9.5

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

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

* [PATCH 09/14] drm/i915: setup scalers for crtc_compute_config
  2015-04-07 22:28 [PATCH 00/14] skylake display scalers Chandra Konduru
                   ` (7 preceding siblings ...)
  2015-04-07 22:28 ` [PATCH 08/14] drm/i915: Preserve scaler state when clearing crtc_state Chandra Konduru
@ 2015-04-07 22:28 ` Chandra Konduru
  2015-04-09 21:51   ` Matt Roper
  2015-04-09 23:42   ` Chandra Konduru
  2015-04-07 22:28 ` [PATCH 10/14] drm/i915: Ensure setting up scalers into staged crtc_state Chandra Konduru
                   ` (6 subsequent siblings)
  15 siblings, 2 replies; 54+ messages in thread
From: Chandra Konduru @ 2015-04-07 22:28 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira, daniel.vetter

Added intel_atomic_setup_scalers to setup scalers based on
staged scaling requests from a crtc and its planes. If staged
requests are supportable, this function assigns scalers to
requested planes and crtc. Note that the scaler assignement
itself is staged into crtc_state and respective plane_states
for later commit after all checks have been done.

overall high level flow:
 - scaler requests are staged into crtc_state by planes/crtc
 - check whether staged scaling requests can be supported
 - add planes using scalers that aren't in current transaction
 - assign scalers to requested users
 - as part of plane commit, scalers will be committed
   (i.e., either attached or detached) to respective planes in hw
 - as part of crtc_commit, scaler will be either attached or detached
   to crtc in hw

crtc_compute_config calls intel_atomic_setup_scalers() to start
scaler assignments as per scaler state in crtc config. This call
should be moved to atomic crtc once it is available.

v2:
-removed a log message (me)
-changed input parameter to crtc_state (me)

v3:
-remove assigning plane_state returned by drm_atomic_get_plane_state (Matt)
-fail if there is an error from drm_atomic_get_plane_state (Matt)

v4:
-changes to align with updated scaler structure (Matt, me)

Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
---
 drivers/gpu/drm/i915/intel_atomic.c  |  137 ++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_display.c |   10 ++-
 drivers/gpu/drm/i915/intel_drv.h     |    3 +
 3 files changed, 149 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 3903b90..ac317b4 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -241,3 +241,140 @@ intel_crtc_destroy_state(struct drm_crtc *crtc,
 {
 	drm_atomic_helper_crtc_destroy_state(crtc, state);
 }
+
+/**
+ * intel_atomic_setup_scalers() - setup scalers for crtc per staged requests
+ * @dev: DRM device
+ * @crtc: intel crtc
+ * @crtc_state: incoming crtc_state to validate and setup scalers
+ *
+ * This function sets up scalers based on staged scaling requests for
+ * a @crtc and its planes. It is called from crtc level check path. If request
+ * is a supportable request, it attaches scalers to requested planes and crtc.
+ *
+ * This function takes into account the current scaler(s) in use by any planes
+ * not being part of this atomic state
+ *
+ *  Returns:
+ *         0 - scalers were setup succesfully
+ *         error code - otherwise
+ */
+int intel_atomic_setup_scalers(struct drm_device *dev,
+	struct intel_crtc *intel_crtc,
+	struct intel_crtc_state *crtc_state)
+{
+	struct drm_plane *plane = NULL;
+	struct intel_plane *intel_plane;
+	struct intel_plane_state *plane_state = NULL;
+	struct intel_crtc_scaler_state *scaler_state;
+	struct drm_atomic_state *drm_state;
+	int num_scalers_need;
+	int i, j;
+
+	if (INTEL_INFO(dev)->gen < 9 || !intel_crtc || !crtc_state)
+		return 0;
+
+	scaler_state = &crtc_state->scaler_state;
+	drm_state = crtc_state->base.state;
+
+	num_scalers_need = hweight32(scaler_state->scaler_users);
+	DRM_DEBUG_KMS("crtc_state = %p need = %d avail = %d scaler_users = 0x%x\n",
+		crtc_state, num_scalers_need, intel_crtc->num_scalers,
+		scaler_state->scaler_users);
+
+	/*
+	 * High level flow:
+	 * - staged scaler requests are already in scaler_state->scaler_users
+	 * - check whether staged scaling requests can be supported
+	 * - add planes using scalers that aren't in current transaction
+	 * - assign scalers to requested users
+	 * - as part of plane commit, scalers will be committed
+	 *   (i.e., either attached or detached) to respective planes in hw
+	 * - as part of crtc_commit, scaler will be either attached or detached
+	 *   to crtc in hw
+	 */
+
+	/* fail if required scalers > available scalers */
+	if (num_scalers_need > intel_crtc->num_scalers){
+		DRM_DEBUG_KMS("Too many scaling requests %d > %d\n",
+			num_scalers_need, intel_crtc->num_scalers);
+		return -EINVAL;
+	}
+
+	/* walkthrough scaler_users bits and start assigning scalers */
+	for (i = 0; i < sizeof(scaler_state->scaler_users) * 8; i++) {
+		int *scaler_id;
+
+		/* skip if scaler not required */
+		if (!(scaler_state->scaler_users & (1 << i)))
+			continue;
+
+		if (i == SKL_CRTC_INDEX) {
+			/* panel fitter case: assign as a crtc scaler */
+			scaler_id = &scaler_state->scaler_id;
+		} else {
+			if (!drm_state)
+				continue;
+
+			/* plane scaler case: assign as a plane scaler */
+			/* find the plane that set the bit as scaler_user */
+			plane = drm_state->planes[i];
+
+			/*
+			 * to enable/disable hq mode, add planes that are using scaler
+			 * into this transaction
+			 */
+			if (!plane) {
+				struct drm_plane_state *state;
+				plane = drm_plane_from_index(dev, i);
+				state = drm_atomic_get_plane_state(drm_state, plane);
+				if (IS_ERR(state)) {
+					DRM_DEBUG_KMS("Failed to add [PLANE:%d] to drm_state\n",
+						plane->base.id);
+					return PTR_ERR(state);
+				}
+			}
+
+			intel_plane = to_intel_plane(plane);
+
+			/* plane on different crtc cannot be a scaler user of this crtc */
+			if (WARN_ON(intel_plane->pipe != intel_crtc->pipe)) {
+				continue;
+			}
+
+			plane_state = to_intel_plane_state(drm_state->plane_states[i]);
+			scaler_id = &plane_state->scaler_id;
+		}
+
+		if (*scaler_id < 0) {
+			/* find a free scaler */
+			for (j = 0; j < intel_crtc->num_scalers; j++) {
+				if (!scaler_state->scalers[j].in_use) {
+					scaler_state->scalers[j].in_use = 1;
+					*scaler_id = scaler_state->scalers[j].id;
+					DRM_DEBUG_KMS("Attached scaler id %u.%u to %s:%d\n",
+						intel_crtc->pipe,
+						i == SKL_CRTC_INDEX ? scaler_state->scaler_id :
+							plane_state->scaler_id,
+						i == SKL_CRTC_INDEX ? "CRTC" : "PLANE",
+						i == SKL_CRTC_INDEX ?  intel_crtc->base.base.id :
+						plane->base.id);
+					break;
+				}
+			}
+		}
+
+		if (WARN_ON(*scaler_id < 0)) {
+			DRM_DEBUG_KMS("Cannot find scaler for %s:%d\n",
+				i == SKL_CRTC_INDEX ? "CRTC" : "PLANE",
+				i == SKL_CRTC_INDEX ? intel_crtc->base.base.id:plane->base.id);
+			continue;
+		}
+
+		/* set scaler mode */
+		scaler_state->scalers[*scaler_id].mode = (num_scalers_need == 1) ?
+			PS_SCALER_MODE_HQ : PS_SCALER_MODE_DYN;
+	}
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f1051f0..9691768 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5809,6 +5809,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	int ret;
 
 	/* FIXME should check pixel clock limits on all platforms */
 	if (INTEL_INFO(dev)->gen < 4) {
@@ -5863,7 +5864,14 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
 	if (pipe_config->has_pch_encoder)
 		return ironlake_fdi_compute_config(crtc, pipe_config);
 
-	return 0;
+	/* FIXME: remove below call once atomic mode set is place and all crtc
+	 * related checks called from atomic_crtc_check function */
+	ret = 0;
+	DRM_DEBUG_KMS("intel_crtc = %p drm_state (pipe_config->base.state) = %p\n",
+		crtc, pipe_config->base.state);
+	ret = intel_atomic_setup_scalers(dev, crtc, pipe_config);
+
+	return ret;
 }
 
 static int skylake_get_display_clock_speed(struct drm_device *dev)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index adca692..f9614fb 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1382,6 +1382,9 @@ intel_atomic_get_crtc_state(struct drm_atomic_state *state,
 
 	return to_intel_crtc_state(crtc_state);
 }
+int intel_atomic_setup_scalers(struct drm_device *dev,
+	struct intel_crtc *intel_crtc,
+	struct intel_crtc_state *crtc_state);
 
 /* intel_atomic_plane.c */
 struct intel_plane_state *intel_create_plane_state(struct drm_plane *plane);
-- 
1.7.9.5

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

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

* [PATCH 10/14] drm/i915: Ensure setting up scalers into staged crtc_state
  2015-04-07 22:28 [PATCH 00/14] skylake display scalers Chandra Konduru
                   ` (8 preceding siblings ...)
  2015-04-07 22:28 ` [PATCH 09/14] drm/i915: setup scalers for crtc_compute_config Chandra Konduru
@ 2015-04-07 22:28 ` Chandra Konduru
  2015-04-07 22:28 ` [PATCH 11/14] drm/i915: copy staged scaler state from drm state to crtc->config Chandra Konduru
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 54+ messages in thread
From: Chandra Konduru @ 2015-04-07 22:28 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira, daniel.vetter

From intel_atomic_check, call intel_atomic_setup_scalers() to
assign scalers based on staged scaling requests. Fail the
transaction if setup returns error.

Setting up of scalers should be moved to atomic crtc check  once
atomic crtc is ready.

v2:
-updated parameter passing to setup_scalers (me)

Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
---
 drivers/gpu/drm/i915/intel_atomic.c |   11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index ac317b4..9663d4d 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -48,6 +48,8 @@ int intel_atomic_check(struct drm_device *dev,
 	int ncrtcs = dev->mode_config.num_crtc;
 	int nconnectors = dev->mode_config.num_connector;
 	enum pipe nuclear_pipe = INVALID_PIPE;
+	struct intel_crtc *nuclear_crtc = NULL;
+	struct intel_crtc_state *crtc_state = NULL;
 	int ret;
 	int i;
 	bool not_nuclear = false;
@@ -78,6 +80,10 @@ int intel_atomic_check(struct drm_device *dev,
 		struct intel_crtc *crtc = to_intel_crtc(state->crtcs[i]);
 		if (crtc && crtc->pipe != nuclear_pipe)
 			not_nuclear = true;
+		if (crtc && crtc->pipe == nuclear_pipe) {
+			nuclear_crtc = crtc;
+			crtc_state = to_intel_crtc_state(state->crtc_states[i]);
+		}
 	}
 	for (i = 0; i < nconnectors; i++)
 		if (state->connectors[i] != NULL)
@@ -92,6 +98,11 @@ int intel_atomic_check(struct drm_device *dev,
 	if (ret)
 		return ret;
 
+	/* FIXME: move to crtc atomic check function once it is ready */
+	ret = intel_atomic_setup_scalers(dev, nuclear_crtc, crtc_state);
+	if (ret)
+		return ret;
+
 	return ret;
 }
 
-- 
1.7.9.5

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

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

* [PATCH 11/14] drm/i915: copy staged scaler state from drm state to crtc->config.
  2015-04-07 22:28 [PATCH 00/14] skylake display scalers Chandra Konduru
                   ` (9 preceding siblings ...)
  2015-04-07 22:28 ` [PATCH 10/14] drm/i915: Ensure setting up scalers into staged crtc_state Chandra Konduru
@ 2015-04-07 22:28 ` Chandra Konduru
  2015-04-07 22:28 ` [PATCH 12/14] drm/i915: skylake panel fitting using shared scalers Chandra Konduru
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 54+ messages in thread
From: Chandra Konduru @ 2015-04-07 22:28 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira, daniel.vetter

This is required for commit to perform as per staged assignment
of scalers until atomic crtc commit function is available.

As a place holder doing this copy from intel_atomic_commit for
scaling to operate correctly.

Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
---
 drivers/gpu/drm/i915/intel_atomic.c |   12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 9663d4d..2fc04ec 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -166,6 +166,18 @@ int intel_atomic_commit(struct drm_device *dev,
 		swap(state->plane_states[i], plane->state);
 		plane->state->state = NULL;
 	}
+
+	/* swap crtc_state */
+	for (i = 0; i < dev->mode_config.num_crtc; i++) {
+		struct drm_crtc *crtc = state->crtcs[i];
+		if (!crtc) {
+			continue;
+		}
+
+		to_intel_crtc(crtc)->config->scaler_state =
+			to_intel_crtc_state(state->crtc_states[i])->scaler_state;
+	}
+
 	drm_atomic_helper_commit_planes(dev, state);
 	drm_atomic_helper_wait_for_vblanks(dev, state);
 	drm_atomic_helper_cleanup_planes(dev, state);
-- 
1.7.9.5

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

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

* [PATCH 12/14] drm/i915: skylake panel fitting using shared scalers
  2015-04-07 22:28 [PATCH 00/14] skylake display scalers Chandra Konduru
                   ` (10 preceding siblings ...)
  2015-04-07 22:28 ` [PATCH 11/14] drm/i915: copy staged scaler state from drm state to crtc->config Chandra Konduru
@ 2015-04-07 22:28 ` Chandra Konduru
  2015-04-07 22:28 ` [PATCH 13/14] drm/i915: skylake primary plane scaling " Chandra Konduru
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 54+ messages in thread
From: Chandra Konduru @ 2015-04-07 22:28 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira, daniel.vetter

Enabling skylake panel fitting feature using shared scalers

v2:
-added force detach parameter for pfit disable purpose (me)
-read crtc scaler state from hw state (Daniel)
-replaced both skylake_pfit_enable and disable with skylake_pfit_update (me)
-added scaler id check to intel_pipe_config_compare (Daniel)

v3:
-updated function header to kerneldoc format (Matt)
-dropped need_scaling checks (Matt)

v4:
-move clearing of scaler id from commit path to check path (Matt)
-updated colorkey checks based on recent updates (me)
-squashed scaler check while enabling colorkey to here (me)
-use values in plane_state->src as regular integers (me)
-changes made not to modify state in commit path (Matt)

v5:
-squashed helper function to update scaler users to here (Matt)
-squashed helper function to detach scaler to here (Matt, me)
-changes to align with updated scaler structures (Matt, me)

Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |  250 ++++++++++++++++++++++++++++++----
 drivers/gpu/drm/i915/intel_dp.c      |    8 ++
 drivers/gpu/drm/i915/intel_drv.h     |    4 +
 3 files changed, 235 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9691768..aa4da1f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2938,6 +2938,35 @@ unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
 	return i915_gem_obj_ggtt_offset_view(obj, view);
 }
 
+/*
+ * This function detaches (aka. unbinds) unused scalers in hardware
+ */
+void skl_detach_scalers(struct intel_crtc *intel_crtc)
+{
+	struct drm_device *dev;
+	struct drm_i915_private *dev_priv;
+	struct intel_crtc_scaler_state *scaler_state;
+	int i;
+
+	if (!intel_crtc || !intel_crtc->config)
+		return;
+
+	dev = intel_crtc->base.dev;
+	dev_priv = dev->dev_private;
+	scaler_state = &intel_crtc->config->scaler_state;
+
+	/* loop through and disable scalers that aren't in use */
+	for (i = 0; i < intel_crtc->num_scalers; i++) {
+		if (!scaler_state->scalers[i].in_use) {
+			I915_WRITE(SKL_PS_CTRL(intel_crtc->pipe, i), 0);
+			I915_WRITE(SKL_PS_WIN_POS(intel_crtc->pipe, i), 0);
+			I915_WRITE(SKL_PS_WIN_SZ(intel_crtc->pipe, i), 0);
+			DRM_DEBUG_KMS("CRTC:%d Disabled scaler id %u.%u\n",
+				intel_crtc->base.base.id, intel_crtc->pipe, i);
+		}
+	}
+}
+
 static void skylake_update_primary_plane(struct drm_crtc *crtc,
 					 struct drm_framebuffer *fb,
 					 int x, int y)
@@ -4253,16 +4282,175 @@ static void cpt_verify_modeset(struct drm_device *dev, int pipe)
 	}
 }
 
-static void skylake_pfit_enable(struct intel_crtc *crtc)
+/**
+ * skl_update_scaler_users - Stages update to crtc's scaler state
+ * @intel_crtc: crtc
+ * @crtc_state: crtc_state
+ * @plane: plane (NULL indicates crtc is requesting update)
+ * @plane_state: plane's state
+ * @force_detach: request unconditional detachment of scaler
+ *
+ * This function updates scaler state for requested plane or crtc.
+ * To request scaler usage update for a plane, caller shall pass plane pointer.
+ * To request scaler usage update for crtc, caller shall pass plane pointer
+ * as NULL.
+ *
+ * Return
+ *     0 - scaler_usage updated successfully
+ *    error - requested scaling cannot be supported or other error condition
+ */
+int
+skl_update_scaler_users(
+	struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state,
+	struct intel_plane *intel_plane, struct intel_plane_state *plane_state,
+	int force_detach)
+{
+	int need_scaling;
+	int idx;
+	int src_w, src_h, dst_w, dst_h;
+	int *scaler_id;
+	struct drm_framebuffer *fb;
+	struct intel_crtc_scaler_state *scaler_state;
+
+	if (!intel_crtc || !crtc_state)
+		return 0;
+
+	scaler_state = &crtc_state->scaler_state;
+
+	idx = intel_plane ? drm_plane_index(&intel_plane->base) : SKL_CRTC_INDEX;
+	fb = intel_plane ? plane_state->base.fb : NULL;
+
+	if (intel_plane) {
+		src_w = drm_rect_width(&plane_state->src) >> 16;
+		src_h = drm_rect_height(&plane_state->src) >> 16;
+		dst_w = drm_rect_width(&plane_state->dst);
+		dst_h = drm_rect_height(&plane_state->dst);
+		scaler_id = &plane_state->scaler_id;
+	} else {
+		struct drm_display_mode *adjusted_mode =
+			&crtc_state->base.adjusted_mode;
+		src_w = crtc_state->pipe_src_w;
+		src_h = crtc_state->pipe_src_h;
+		dst_w = adjusted_mode->hdisplay;
+		dst_h = adjusted_mode->vdisplay;
+		scaler_id = &scaler_state->scaler_id;
+	}
+	need_scaling = (src_w != dst_w || src_h != dst_h);
+
+	/*
+	 * if plane is being disabled or scaler is no more required or force detach
+	 *  - free scaler binded to this plane/crtc
+	 *  - in order to do this, update crtc->scaler_usage
+	 *
+	 * Here scaler state in crtc_state is set free so that
+	 * scaler can be assigned to other user. Actual register
+	 * 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 || (intel_plane &&
+		(!fb || !plane_state->visible))) {
+		if (*scaler_id >= 0) {
+			scaler_state->scaler_users &= ~(1 << idx);
+			scaler_state->scalers[*scaler_id].in_use = 0;
+
+			DRM_DEBUG_KMS("Staged freeing scaler id %d.%d from %s:%d "
+				"crtc_state = %p scaler_users = 0x%x\n",
+				intel_crtc->pipe, *scaler_id, intel_plane ? "PLANE" : "CRTC",
+				intel_plane ? intel_plane->base.base.id :
+				intel_crtc->base.base.id, crtc_state,
+				scaler_state->scaler_users);
+			*scaler_id = -1;
+		}
+		return 0;
+	}
+
+	/* range checks */
+	if (src_w < SKL_MIN_SRC_W || src_h < SKL_MIN_SRC_H ||
+		dst_w < SKL_MIN_DST_W || dst_h < SKL_MIN_DST_H ||
+
+		src_w > SKL_MAX_SRC_W || src_h > SKL_MAX_SRC_H ||
+		dst_w > SKL_MAX_DST_W || dst_h > SKL_MAX_DST_H) {
+		DRM_DEBUG_KMS("%s:%d scaler_user index %u.%u: src %ux%u dst %ux%u "
+			"size is out of scaler range\n",
+			intel_plane ? "PLANE" : "CRTC",
+			intel_plane ? intel_plane->base.base.id : intel_crtc->base.base.id,
+			intel_crtc->pipe, idx, src_w, src_h, dst_w, dst_h);
+		return -EINVAL;
+	}
+
+	/* check colorkey */
+	if (intel_plane && intel_plane->ckey.flags != I915_SET_COLORKEY_NONE) {
+		DRM_DEBUG_KMS("PLANE:%d scaling with color key not allowed",
+			intel_plane->base.base.id);
+		return -EINVAL;
+	}
+
+	/* Check src format */
+	if (intel_plane) {
+		switch (fb->pixel_format) {
+		case DRM_FORMAT_RGB565:
+		case DRM_FORMAT_XBGR8888:
+		case DRM_FORMAT_XRGB8888:
+		case DRM_FORMAT_ABGR8888:
+		case DRM_FORMAT_ARGB8888:
+		case DRM_FORMAT_XRGB2101010:
+		case DRM_FORMAT_ARGB2101010:
+		case DRM_FORMAT_XBGR2101010:
+		case DRM_FORMAT_ABGR2101010:
+		case DRM_FORMAT_YUYV:
+		case DRM_FORMAT_YVYU:
+		case DRM_FORMAT_UYVY:
+		case DRM_FORMAT_VYUY:
+			break;
+		default:
+			DRM_DEBUG_KMS("PLANE:%d FB:%d unsupported scaling format 0x%x\n",
+				intel_plane->base.base.id, fb->base.id, fb->pixel_format);
+			return -EINVAL;
+		}
+	}
+
+	/* mark this plane as a scaler user in crtc_state */
+	scaler_state->scaler_users |= (1 << idx);
+	DRM_DEBUG_KMS("%s:%d staged scaling request for %ux%u->%ux%u "
+		"crtc_state = %p scaler_users = 0x%x\n",
+		intel_plane ? "PLANE" : "CRTC",
+		intel_plane ? intel_plane->base.base.id : intel_crtc->base.base.id,
+		src_w, src_h, dst_w, dst_h, crtc_state, scaler_state->scaler_users);
+	return 0;
+}
+
+static void skylake_pfit_update(struct intel_crtc *crtc, int enable)
 {
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int pipe = crtc->pipe;
+	struct intel_crtc_scaler_state *scaler_state =
+		&crtc->config->scaler_state;
+
+	DRM_DEBUG_KMS("for crtc_state = %p\n", crtc->config);
+
+	/* To update pfit, first update scaler state */
+	skl_update_scaler_users(crtc, crtc->config, NULL, NULL, !enable);
+	intel_atomic_setup_scalers(crtc->base.dev, crtc, crtc->config);
+	skl_detach_scalers(crtc);
+	if (!enable)
+		return;
 
 	if (crtc->config->pch_pfit.enabled) {
-		I915_WRITE(PS_CTL(pipe), PS_ENABLE);
-		I915_WRITE(PS_WIN_POS(pipe), crtc->config->pch_pfit.pos);
-		I915_WRITE(PS_WIN_SZ(pipe), crtc->config->pch_pfit.size);
+		int id;
+
+		if (WARN_ON(crtc->config->scaler_state.scaler_id < 0)) {
+			DRM_ERROR("Requesting pfit without getting a scaler first\n");
+			return;
+		}
+
+		id = scaler_state->scaler_id;
+		I915_WRITE(SKL_PS_CTRL(pipe, id), PS_SCALER_EN |
+			PS_FILTER_MEDIUM | scaler_state->scalers[id].mode);
+		I915_WRITE(SKL_PS_WIN_POS(pipe, id), crtc->config->pch_pfit.pos);
+		I915_WRITE(SKL_PS_WIN_SZ(pipe, id), crtc->config->pch_pfit.size);
+
+		DRM_DEBUG_KMS("for crtc_state = %p scaler_id = %d\n", crtc->config, id);
 	}
 }
 
@@ -4667,7 +4855,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 	intel_ddi_enable_pipe_clock(intel_crtc);
 
 	if (IS_SKYLAKE(dev))
-		skylake_pfit_enable(intel_crtc);
+		skylake_pfit_update(intel_crtc, 1);
 	else
 		ironlake_pfit_enable(intel_crtc);
 
@@ -4703,21 +4891,6 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 	intel_crtc_enable_planes(crtc);
 }
 
-static void skylake_pfit_disable(struct intel_crtc *crtc)
-{
-	struct drm_device *dev = crtc->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	int pipe = crtc->pipe;
-
-	/* To avoid upsetting the power well on haswell only disable the pfit if
-	 * it's in use. The hw state code will make sure we get this right. */
-	if (crtc->config->pch_pfit.enabled) {
-		I915_WRITE(PS_CTL(pipe), 0);
-		I915_WRITE(PS_WIN_POS(pipe), 0);
-		I915_WRITE(PS_WIN_SZ(pipe), 0);
-	}
-}
-
 static void ironlake_pfit_disable(struct intel_crtc *crtc)
 {
 	struct drm_device *dev = crtc->base.dev;
@@ -4830,7 +5003,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
 	intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder);
 
 	if (IS_SKYLAKE(dev))
-		skylake_pfit_disable(intel_crtc);
+		skylake_pfit_update(intel_crtc, 0);
 	else
 		ironlake_pfit_disable(intel_crtc);
 
@@ -8069,14 +8242,28 @@ static void skylake_get_pfit_config(struct intel_crtc *crtc,
 {
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	uint32_t tmp;
+	struct intel_crtc_scaler_state *scaler_state = &pipe_config->scaler_state;
+	uint32_t ps_ctrl = 0;
+	int id = -1;
+	int i;
 
-	tmp = I915_READ(PS_CTL(crtc->pipe));
+	/* find scaler attached to this pipe */
+	for (i = 0; i < crtc->num_scalers; i++) {
+		ps_ctrl = I915_READ(SKL_PS_CTRL(crtc->pipe, i));
+		if (ps_ctrl & PS_SCALER_EN && !(ps_ctrl & PS_PLANE_SEL_MASK)) {
+			id = i;
+			pipe_config->pch_pfit.enabled = true;
+			pipe_config->pch_pfit.pos = I915_READ(SKL_PS_WIN_POS(crtc->pipe, i));
+			pipe_config->pch_pfit.size = I915_READ(SKL_PS_WIN_SZ(crtc->pipe, i));
+			break;
+		}
+	}
 
-	if (tmp & PS_ENABLE) {
-		pipe_config->pch_pfit.enabled = true;
-		pipe_config->pch_pfit.pos = I915_READ(PS_WIN_POS(crtc->pipe));
-		pipe_config->pch_pfit.size = I915_READ(PS_WIN_SZ(crtc->pipe));
+	scaler_state->scaler_id = id;
+	if (id >= 0) {
+		scaler_state->scaler_users |= (1 << SKL_CRTC_INDEX);
+	} else {
+		scaler_state->scaler_users &= ~(1 << SKL_CRTC_INDEX);
 	}
 }
 
@@ -8710,12 +8897,19 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
 
 	intel_get_pipe_timings(crtc, pipe_config);
 
+	if (INTEL_INFO(dev)->gen >= 9) {
+		skl_init_scalers(dev, crtc, pipe_config);
+	}
+
 	pfit_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe);
 	if (intel_display_power_is_enabled(dev_priv, pfit_domain)) {
 		if (IS_SKYLAKE(dev))
 			skylake_get_pfit_config(crtc, pipe_config);
 		else
 			ironlake_get_pfit_config(crtc, pipe_config);
+	} else {
+		pipe_config->scaler_state.scaler_id = -1;
+		pipe_config->scaler_state.scaler_users &= ~(1 << SKL_CRTC_INDEX);
 	}
 
 	if (IS_HASWELL(dev))
@@ -11222,6 +11416,8 @@ intel_pipe_config_compare(struct drm_device *dev,
 		PIPE_CONF_CHECK_I(pch_pfit.size);
 	}
 
+	PIPE_CONF_CHECK_I(scaler_state.scaler_id);
+
 	/* BDW+ don't expose a synchronous way to read the state */
 	if (IS_HASWELL(dev))
 		PIPE_CONF_CHECK_I(ips_enabled);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 7936155..c19698f 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1351,6 +1351,14 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 	if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) {
 		intel_fixed_panel_mode(intel_connector->panel.fixed_mode,
 				       adjusted_mode);
+
+		if (INTEL_INFO(dev)->gen >= 9) {
+			int ret;
+			ret = skl_update_scaler_users(intel_crtc, pipe_config, NULL, NULL, 0);
+			if (ret)
+				return ret;
+		}
+
 		if (!HAS_PCH_SPLIT(dev))
 			intel_gmch_panel_fitting(intel_crtc, pipe_config,
 						 intel_connector->panel.fitting_mode);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index f9614fb..7b28bff 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1121,6 +1121,10 @@ void intel_mode_from_pipe_config(struct drm_display_mode *mode,
 				 struct intel_crtc_state *pipe_config);
 void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc);
 void intel_modeset_preclose(struct drm_device *dev, struct drm_file *file);
+void skl_detach_scalers(struct intel_crtc *intel_crtc);
+int skl_update_scaler_users(struct intel_crtc *intel_crtc,
+	struct intel_crtc_state *crtc_state, struct intel_plane *intel_plane,
+	struct intel_plane_state *plane_state, int force_detach);
 
 unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
 				     struct drm_i915_gem_object *obj);
-- 
1.7.9.5

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

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

* [PATCH 13/14] drm/i915: skylake primary plane scaling using shared scalers
  2015-04-07 22:28 [PATCH 00/14] skylake display scalers Chandra Konduru
                   ` (11 preceding siblings ...)
  2015-04-07 22:28 ` [PATCH 12/14] drm/i915: skylake panel fitting using shared scalers Chandra Konduru
@ 2015-04-07 22:28 ` Chandra Konduru
  2015-04-09 21:51   ` Matt Roper
                     ` (4 more replies)
  2015-04-07 22:28 ` [PATCH 14/14] drm/i915: skylake sprite " Chandra Konduru
                   ` (2 subsequent siblings)
  15 siblings, 5 replies; 54+ messages in thread
From: Chandra Konduru @ 2015-04-07 22:28 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira, daniel.vetter

This patch enables skylake primary plane scaling using shared
scalers atomic desgin.

v2:
-use single copy of scaler limits (Matt)

v3:
-move detach_scalers to crtc commit path (Matt)
-use values in plane_state->src as regular integers (me)

v4:
-changes to align with updated scaler structures (Matt, me)
-keep plane src rect in 16.16 format (Matt, Daniel)

Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
---
 drivers/gpu/drm/i915/intel_atomic.c  |    5 +-
 drivers/gpu/drm/i915/intel_display.c |   96 ++++++++++++++++++++++++++++++++--
 drivers/gpu/drm/i915/intel_drv.h     |    1 +
 drivers/gpu/drm/i915/intel_sprite.c  |    9 ++++
 4 files changed, 105 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 2fc04ec..8f759c6 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -167,7 +167,7 @@ int intel_atomic_commit(struct drm_device *dev,
 		plane->state->state = NULL;
 	}
 
-	/* swap crtc_state */
+	/* swap crtc_scaler_state */
 	for (i = 0; i < dev->mode_config.num_crtc; i++) {
 		struct drm_crtc *crtc = state->crtcs[i];
 		if (!crtc) {
@@ -176,6 +176,9 @@ int intel_atomic_commit(struct drm_device *dev,
 
 		to_intel_crtc(crtc)->config->scaler_state =
 			to_intel_crtc_state(state->crtc_states[i])->scaler_state;
+
+		if (INTEL_INFO(dev)->gen >= 9)
+			skl_detach_scalers(to_intel_crtc(crtc));
 	}
 
 	drm_atomic_helper_commit_planes(dev, state);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index aa4da1f..c7ee232 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2978,6 +2978,14 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc,
 	int pipe = intel_crtc->pipe;
 	u32 plane_ctl, stride_div;
 	unsigned long surf_addr;
+	struct intel_crtc_state *crtc_state = intel_crtc->config;
+	struct intel_plane_state *plane_state;
+	int src_x = 0, src_y = 0, src_w = 0, src_h = 0;
+	int dst_x = 0, dst_y = 0, dst_w = 0, dst_h = 0;
+	int scaler_id = -1;
+
+	plane_state = crtc->primary ?
+		to_intel_plane_state(crtc->primary->state) : NULL;
 
 	if (!intel_crtc->primary_enabled) {
 		I915_WRITE(PLANE_CTL(pipe, 0), 0);
@@ -3046,12 +3054,40 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc,
 					       fb->pixel_format);
 	surf_addr = intel_plane_obj_offset(to_intel_plane(crtc->primary), obj);
 
+	if (plane_state) {
+		scaler_id = plane_state->scaler_id;
+		src_x = plane_state->src.x1 >> 16;
+		src_y = plane_state->src.y1 >> 16;
+		src_w = drm_rect_width(&plane_state->src) >> 16;
+		src_h = drm_rect_height(&plane_state->src) >> 16;
+		dst_x = plane_state->dst.x1;
+		dst_y = plane_state->dst.y1;
+		dst_w = drm_rect_width(&plane_state->dst);
+		dst_h = drm_rect_height(&plane_state->dst);
+	}
+
 	I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
 	I915_WRITE(PLANE_POS(pipe, 0), 0);
+
+	if (src_w && src_h && dst_w && dst_h && scaler_id >= 0) {
+		uint32_t ps_ctrl = 0;
+
+		WARN_ON(x != src_x || y != src_y);
+		ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(0) |
+			crtc_state->scaler_state.scalers[scaler_id].mode;
+		I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
+		I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
+		I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (dst_x << 16) | dst_y);
+		I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id), (dst_w << 16) | dst_h);
+
+		I915_WRITE(PLANE_SIZE(pipe, 0), ((src_h - 1) << 16) | (src_w - 1));
+	} else {
+		I915_WRITE(PLANE_SIZE(pipe, 0),
+			(intel_crtc->config->pipe_src_h - 1) << 16 |
+			(intel_crtc->config->pipe_src_w - 1));
+	}
+
 	I915_WRITE(PLANE_OFFSET(pipe, 0), (y << 16) | x);
-	I915_WRITE(PLANE_SIZE(pipe, 0),
-		   (intel_crtc->config->pipe_src_h - 1) << 16 |
-		   (intel_crtc->config->pipe_src_w - 1));
 	I915_WRITE(PLANE_STRIDE(pipe, 0), fb->pitches[0] / stride_div);
 	I915_WRITE(PLANE_SURF(pipe, 0), surf_addr);
 
@@ -12778,6 +12814,36 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
 	}
 }
 
+int
+skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state)
+{
+	int max_scale;
+	struct drm_device *dev;
+	struct drm_i915_private *dev_priv;
+	int crtc_clock, cdclk;
+
+	if (!intel_crtc || !crtc_state)
+		return DRM_PLANE_HELPER_NO_SCALING;
+
+	dev = intel_crtc->base.dev;
+	dev_priv = dev->dev_private;
+	crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
+	cdclk = dev_priv->display.get_display_clock_speed(dev);
+
+	if (!crtc_clock || !cdclk)
+		return DRM_PLANE_HELPER_NO_SCALING;
+
+	/*
+	 * skl max scale is lower of:
+	 *    close to 3 but not 3, -1 is for that purpose
+	 *            or
+	 *    cdclk/crtc_clock
+	 */
+	max_scale = min((1 << 16) * 3 - 1, (1 << 8) * ((cdclk << 8) / crtc_clock));
+
+	return max_scale;
+}
+
 static int
 intel_check_primary_plane(struct drm_plane *plane,
 			  struct intel_plane_state *state)
@@ -12786,19 +12852,29 @@ intel_check_primary_plane(struct drm_plane *plane,
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_crtc *crtc = state->base.crtc;
 	struct intel_crtc *intel_crtc;
+	struct intel_crtc_state *crtc_state;
 	struct drm_framebuffer *fb = state->base.fb;
 	struct drm_rect *dest = &state->dst;
 	struct drm_rect *src = &state->src;
 	const struct drm_rect *clip = &state->clip;
+	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
+	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
 	int ret;
 
 	crtc = crtc ? crtc : plane->crtc;
 	intel_crtc = to_intel_crtc(crtc);
+	crtc_state = state->base.state ?
+		intel_atomic_get_crtc_state(state->base.state, intel_crtc) : NULL;
+
+	if (INTEL_INFO(dev)->gen >= 9) {
+		min_scale = 1;
+		max_scale = skl_max_scale(intel_crtc, crtc_state);
+	}
 
 	ret = drm_plane_helper_check_update(plane, crtc, fb,
 					    src, dest, clip,
-					    DRM_PLANE_HELPER_NO_SCALING,
-					    DRM_PLANE_HELPER_NO_SCALING,
+					    min_scale,
+					    max_scale,
 					    false, true, &state->visible);
 	if (ret)
 		return ret;
@@ -12842,6 +12918,13 @@ intel_check_primary_plane(struct drm_plane *plane,
 			intel_crtc->atomic.update_wm = true;
 	}
 
+	if (INTEL_INFO(dev)->gen >= 9) {
+		ret = skl_update_scaler_users(intel_crtc, crtc_state,
+			to_intel_plane(plane), state, 0);
+		if (ret)
+			return ret;
+	}
+
 	return 0;
 }
 
@@ -13021,6 +13104,9 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
 
 	primary->can_scale = false;
 	primary->max_downscale = 1;
+	if (INTEL_INFO(dev)->gen >= 9) {
+		primary->can_scale = true;
+	}
 	state->scaler_id = -1;
 	primary->pipe = pipe;
 	primary->plane = pipe;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 7b28bff..0543150 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1125,6 +1125,7 @@ void skl_detach_scalers(struct intel_crtc *intel_crtc);
 int skl_update_scaler_users(struct intel_crtc *intel_crtc,
 	struct intel_crtc_state *crtc_state, struct intel_plane *intel_plane,
 	struct intel_plane_state *plane_state, int force_detach);
+int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state);
 
 unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
 				     struct drm_i915_gem_object *obj);
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index c05fb36..955965c 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -1119,6 +1119,15 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
 	}
 
 	intel_plane = to_intel_plane(plane);
+
+	if (INTEL_INFO(dev)->gen >= 9) {
+		/* plane scaling and colorkey are mutually exclusive */
+		if (to_intel_plane_state(plane->state)->scaler_id >= 0) {
+			DRM_ERROR("colorkey not allowed with scaler\n");
+			return -EINVAL;
+		}
+	}
+
 	intel_plane->ckey = *set;
 
 	/*
-- 
1.7.9.5

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

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

* [PATCH 14/14] drm/i915: skylake sprite plane scaling using shared scalers
  2015-04-07 22:28 [PATCH 00/14] skylake display scalers Chandra Konduru
                   ` (12 preceding siblings ...)
  2015-04-07 22:28 ` [PATCH 13/14] drm/i915: skylake primary plane scaling " Chandra Konduru
@ 2015-04-07 22:28 ` Chandra Konduru
  2015-04-09 23:43   ` Chandra Konduru
  2015-04-15 22:15   ` Chandra Konduru
  2015-04-09 21:53 ` [PATCH 00/14] skylake display scalers Matt Roper
  2015-04-10  9:34 ` Daniel Vetter
  15 siblings, 2 replies; 54+ messages in thread
From: Chandra Konduru @ 2015-04-07 22:28 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira, daniel.vetter

This patch enables skylake sprite plane display scaling using shared
scalers atomic desgin.

v2:
-use single copy of scaler limits (Matt)

v3:
-detaching scalers moved to crtc commit path (Matt)

v4:
-changes to align with updated scaler structures (Matt, me)
-keep sprite src rect in 16.16 format (Matt, Daniel)

Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
---
 drivers/gpu/drm/i915/intel_sprite.c |   64 +++++++++++++++++++++++++++--------
 1 file changed, 50 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 955965c..ae503ee 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -33,6 +33,7 @@
 #include <drm/drm_crtc.h>
 #include <drm/drm_fourcc.h>
 #include <drm/drm_rect.h>
+#include <drm/drm_atomic.h>
 #include <drm/drm_plane_helper.h>
 #include "intel_drv.h"
 #include <drm/i915_drm.h>
@@ -194,6 +195,8 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
 	int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
 	const struct drm_intel_sprite_colorkey *key = &intel_plane->ckey;
 	unsigned long surf_addr;
+	struct intel_crtc_state *crtc_state = to_intel_crtc(crtc)->config;
+	int scaler_id;
 
 	plane_ctl = PLANE_CTL_ENABLE |
 		PLANE_CTL_PIPE_CSC_ENABLE;
@@ -264,6 +267,8 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
 	stride_div = intel_fb_stride_alignment(dev, fb->modifier[0],
 					       fb->pixel_format);
 
+	scaler_id = to_intel_plane_state(drm_plane->state)->scaler_id;
+
 	/* Sizes are 0 based */
 	src_w--;
 	src_h--;
@@ -283,10 +288,29 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
 
 	surf_addr = intel_plane_obj_offset(intel_plane, obj);
 
+	/* program plane scaler */
+	if (scaler_id >= 0) {
+		uint32_t ps_ctrl = 0;
+
+		DRM_DEBUG_KMS("plane = %d PS_PLANE_SEL(plane) = 0x%x\n", plane,
+			PS_PLANE_SEL(plane));
+		ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(plane) |
+			crtc_state->scaler_state.scalers[scaler_id].mode;
+		I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
+		I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
+		I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
+		I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id),
+			((crtc_w + 1) << 16)|(crtc_h + 1));
+
+		I915_WRITE(PLANE_POS(pipe, plane), 0);
+		I915_WRITE(PLANE_SIZE(pipe, plane), (src_h << 16) | src_w);
+	} else {
+		I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x);
+		I915_WRITE(PLANE_SIZE(pipe, plane), (crtc_h << 16) | crtc_w);
+	}
+
 	I915_WRITE(PLANE_OFFSET(pipe, plane), (y << 16) | x);
 	I915_WRITE(PLANE_STRIDE(pipe, plane), fb->pitches[0] / stride_div);
-	I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x);
-	I915_WRITE(PLANE_SIZE(pipe, plane), (crtc_h << 16) | crtc_w);
 	I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl);
 	I915_WRITE(PLANE_SURF(pipe, plane), surf_addr);
 	POSTING_READ(PLANE_SURF(pipe, plane));
@@ -863,7 +887,9 @@ static int
 intel_check_sprite_plane(struct drm_plane *plane,
 			 struct intel_plane_state *state)
 {
+	struct drm_device *dev = plane->dev;
 	struct intel_crtc *intel_crtc = to_intel_crtc(state->base.crtc);
+	struct intel_crtc_state *crtc_state;
 	struct intel_plane *intel_plane = to_intel_plane(plane);
 	struct drm_framebuffer *fb = state->base.fb;
 	int crtc_x, crtc_y;
@@ -875,8 +901,11 @@ intel_check_sprite_plane(struct drm_plane *plane,
 	int hscale, vscale;
 	int max_scale, min_scale;
 	int pixel_size;
+	int ret;
 
 	intel_crtc = intel_crtc ? intel_crtc : to_intel_crtc(plane->crtc);
+	crtc_state = state->base.state ?
+		intel_atomic_get_crtc_state(state->base.state, intel_crtc) : NULL;
 
 	if (!fb) {
 		state->visible = false;
@@ -903,6 +932,11 @@ intel_check_sprite_plane(struct drm_plane *plane,
 	max_scale = intel_plane->max_downscale << 16;
 	min_scale = intel_plane->can_scale ? 1 : (1 << 16);
 
+	if (INTEL_INFO(dev)->gen >= 9) {
+		min_scale = 1;
+		max_scale = skl_max_scale(intel_crtc, crtc_state);
+	}
+
 	drm_rect_rotate(src, fb->width << 16, fb->height << 16,
 			state->base.rotation);
 
@@ -998,8 +1032,8 @@ intel_check_sprite_plane(struct drm_plane *plane,
 		width_bytes = ((src_x * pixel_size) & 63) +
 					src_w * pixel_size;
 
-		if (src_w > 2048 || src_h > 2048 ||
-		    width_bytes > 4096 || fb->pitches[0] > 4096) {
+		if (INTEL_INFO(dev)->gen < 9 && (src_w > 2048 || src_h > 2048 ||
+		    width_bytes > 4096 || fb->pitches[0] > 4096)) {
 			DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
 			return -EINVAL;
 		}
@@ -1053,6 +1087,13 @@ finish:
 		}
 	}
 
+	if (INTEL_INFO(dev)->gen >= 9) {
+		ret = skl_update_scaler_users(intel_crtc, crtc_state, intel_plane,
+			state, 0);
+		if (ret)
+			return ret;
+	}
+
 	return 0;
 }
 
@@ -1081,10 +1122,10 @@ intel_commit_sprite_plane(struct drm_plane *plane,
 			crtc_y = state->dst.y1;
 			crtc_w = drm_rect_width(&state->dst);
 			crtc_h = drm_rect_height(&state->dst);
-			src_x = state->src.x1;
-			src_y = state->src.y1;
-			src_w = drm_rect_width(&state->src);
-			src_h = drm_rect_height(&state->src);
+			src_x = state->src.x1 >> 16;
+			src_y = state->src.y1 >> 16;
+			src_w = drm_rect_width(&state->src) >> 16;
+			src_h = drm_rect_height(&state->src) >> 16;
 			intel_plane->update_plane(plane, crtc, fb,
 						  crtc_x, crtc_y, crtc_w, crtc_h,
 						  src_x, src_y, src_w, src_h);
@@ -1264,12 +1305,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
 		}
 		break;
 	case 9:
-		/*
-		 * FIXME: Skylake planes can be scaled (with some restrictions),
-		 * but this is for another time.
-		 */
-		intel_plane->can_scale = false;
-		intel_plane->max_downscale = 1;
+		intel_plane->can_scale = true;
 		intel_plane->update_plane = skl_update_plane;
 		intel_plane->disable_plane = skl_disable_plane;
 		state->scaler_id = -1;
-- 
1.7.9.5

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

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

* Re: [PATCH 06/14] drm/i915: Keep sprite plane src rect in 16.16 format
  2015-04-07 22:28 ` [PATCH 06/14] drm/i915: Keep sprite plane src rect in 16.16 format Chandra Konduru
@ 2015-04-09 21:50   ` Matt Roper
  2015-04-09 22:08     ` Konduru, Chandra
  2015-04-09 23:41   ` Chandra Konduru
  1 sibling, 1 reply; 54+ messages in thread
From: Matt Roper @ 2015-04-09 21:50 UTC (permalink / raw)
  To: Chandra Konduru; +Cc: daniel.vetter, intel-gfx, ander.conselvan.de.oliveira

On Tue, Apr 07, 2015 at 03:28:39PM -0700, Chandra Konduru wrote:
> This patch keeps intel_plane_state->src rect back
> into 16.16 format.
> 
> v2:
> -sprite src rect to match primary format (Matt, Daniel)
> 
> Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>

This looks good, and matches what we had discussed, but don't you also
need to add the corresponding unshift in intel_commit_sprite_plane()
when we actually pull the values out and make use of them?  The goal is
to keep the meaning of the structure fields consistent at all times
(16.16 fixed pt), but once we pull the values out of the structure, we
wind up passing them to functions that doing use fixed point, so we do
need to unshift at that point.

It looks like in patch #13 you do switch the low-level
skl_update_plane() to make use of 16.16 input parameters.  However any
commit that we bisect through between #6 and #13 is going to wind up
treating 16.16 values as integer values, which I assume will blow up.
Also, you haven't touched any of the other platforms (ilk, vlv, ivb,
etc.) so they're all still going to have problems.

I think the easiest short-term solution is to do the unshifting in
commit_plane and leave the hardware-specific programming functions
as-is.  Longer term, maybe it makes sense for a future patchset to
change the actual register-programming functions (foo_update_plane) so
that they take a plane_state directly and do their own unshifting?  In
that case we'd need to update them to do their own unshifting, but at
least we wouldn't have to pull all the values out in commit_plane, just
to pass them to these functions.


Matt

> ---
>  drivers/gpu/drm/i915/intel_sprite.c |    8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index ac4aa68..c05fb36 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -1006,10 +1006,10 @@ intel_check_sprite_plane(struct drm_plane *plane,
>  	}
>  
>  	if (state->visible) {
> -		src->x1 = src_x;
> -		src->x2 = src_x + src_w;
> -		src->y1 = src_y;
> -		src->y2 = src_y + src_h;
> +		src->x1 = src_x << 16;
> +		src->x2 = (src_x + src_w) << 16;
> +		src->y1 = src_y << 16;
> +		src->y2 = (src_y + src_h) << 16;
>  	}
>  
>  	dst->x1 = crtc_x;
> -- 
> 1.7.9.5
> 

-- 
Matt Roper
Graphics Software Engineer
IoTG Platform Enabling & Development
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 09/14] drm/i915: setup scalers for crtc_compute_config
  2015-04-07 22:28 ` [PATCH 09/14] drm/i915: setup scalers for crtc_compute_config Chandra Konduru
@ 2015-04-09 21:51   ` Matt Roper
  2015-04-09 22:07     ` Konduru, Chandra
  2015-04-09 23:42   ` Chandra Konduru
  1 sibling, 1 reply; 54+ messages in thread
From: Matt Roper @ 2015-04-09 21:51 UTC (permalink / raw)
  To: Chandra Konduru; +Cc: daniel.vetter, intel-gfx, ander.conselvan.de.oliveira

On Tue, Apr 07, 2015 at 03:28:42PM -0700, Chandra Konduru wrote:
> Added intel_atomic_setup_scalers to setup scalers based on
> staged scaling requests from a crtc and its planes. If staged
> requests are supportable, this function assigns scalers to
> requested planes and crtc. Note that the scaler assignement
> itself is staged into crtc_state and respective plane_states
> for later commit after all checks have been done.
> 
> overall high level flow:
>  - scaler requests are staged into crtc_state by planes/crtc
>  - check whether staged scaling requests can be supported
>  - add planes using scalers that aren't in current transaction
>  - assign scalers to requested users
>  - as part of plane commit, scalers will be committed
>    (i.e., either attached or detached) to respective planes in hw
>  - as part of crtc_commit, scaler will be either attached or detached
>    to crtc in hw
> 
> crtc_compute_config calls intel_atomic_setup_scalers() to start
> scaler assignments as per scaler state in crtc config. This call
> should be moved to atomic crtc once it is available.
> 
> v2:
> -removed a log message (me)
> -changed input parameter to crtc_state (me)
> 
> v3:
> -remove assigning plane_state returned by drm_atomic_get_plane_state (Matt)
> -fail if there is an error from drm_atomic_get_plane_state (Matt)
> 
> v4:
> -changes to align with updated scaler structure (Matt, me)
> 
> Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_atomic.c  |  137 ++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_display.c |   10 ++-
>  drivers/gpu/drm/i915/intel_drv.h     |    3 +
>  3 files changed, 149 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> index 3903b90..ac317b4 100644
> --- a/drivers/gpu/drm/i915/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> @@ -241,3 +241,140 @@ intel_crtc_destroy_state(struct drm_crtc *crtc,
>  {
>  	drm_atomic_helper_crtc_destroy_state(crtc, state);
>  }
> +
> +/**
> + * intel_atomic_setup_scalers() - setup scalers for crtc per staged requests
> + * @dev: DRM device
> + * @crtc: intel crtc
> + * @crtc_state: incoming crtc_state to validate and setup scalers
> + *
> + * This function sets up scalers based on staged scaling requests for
> + * a @crtc and its planes. It is called from crtc level check path. If request
> + * is a supportable request, it attaches scalers to requested planes and crtc.
> + *
> + * This function takes into account the current scaler(s) in use by any planes
> + * not being part of this atomic state
> + *
> + *  Returns:
> + *         0 - scalers were setup succesfully
> + *         error code - otherwise
> + */
> +int intel_atomic_setup_scalers(struct drm_device *dev,
> +	struct intel_crtc *intel_crtc,
> +	struct intel_crtc_state *crtc_state)
> +{
> +	struct drm_plane *plane = NULL;
> +	struct intel_plane *intel_plane;
> +	struct intel_plane_state *plane_state = NULL;
> +	struct intel_crtc_scaler_state *scaler_state;
> +	struct drm_atomic_state *drm_state;
> +	int num_scalers_need;
> +	int i, j;
> +
> +	if (INTEL_INFO(dev)->gen < 9 || !intel_crtc || !crtc_state)
> +		return 0;
> +
> +	scaler_state = &crtc_state->scaler_state;
> +	drm_state = crtc_state->base.state;
> +
> +	num_scalers_need = hweight32(scaler_state->scaler_users);
> +	DRM_DEBUG_KMS("crtc_state = %p need = %d avail = %d scaler_users = 0x%x\n",
> +		crtc_state, num_scalers_need, intel_crtc->num_scalers,
> +		scaler_state->scaler_users);
> +
> +	/*
> +	 * High level flow:
> +	 * - staged scaler requests are already in scaler_state->scaler_users
> +	 * - check whether staged scaling requests can be supported
> +	 * - add planes using scalers that aren't in current transaction
> +	 * - assign scalers to requested users
> +	 * - as part of plane commit, scalers will be committed
> +	 *   (i.e., either attached or detached) to respective planes in hw
> +	 * - as part of crtc_commit, scaler will be either attached or detached
> +	 *   to crtc in hw
> +	 */
> +
> +	/* fail if required scalers > available scalers */
> +	if (num_scalers_need > intel_crtc->num_scalers){
> +		DRM_DEBUG_KMS("Too many scaling requests %d > %d\n",
> +			num_scalers_need, intel_crtc->num_scalers);
> +		return -EINVAL;
> +	}
> +
> +	/* walkthrough scaler_users bits and start assigning scalers */
> +	for (i = 0; i < sizeof(scaler_state->scaler_users) * 8; i++) {
> +		int *scaler_id;
> +
> +		/* skip if scaler not required */
> +		if (!(scaler_state->scaler_users & (1 << i)))
> +			continue;
> +
> +		if (i == SKL_CRTC_INDEX) {
> +			/* panel fitter case: assign as a crtc scaler */
> +			scaler_id = &scaler_state->scaler_id;
> +		} else {
> +			if (!drm_state)
> +				continue;
> +
> +			/* plane scaler case: assign as a plane scaler */
> +			/* find the plane that set the bit as scaler_user */
> +			plane = drm_state->planes[i];
> +
> +			/*
> +			 * to enable/disable hq mode, add planes that are using scaler
> +			 * into this transaction
> +			 */

The code here looks fine, but the reference to "hq mode" kind of comes
out of the blue.  I realize you're setting HQ or DYN down at the bottom
of this function, but there's never really any indication of what those
are or what they mean (or how having the other plane states in the
top-level transaction relates to HQ mode).  I'm assuming what your
comment here is trying to say is that the mode for an already setup and
unchanged plane+scaler might have to change due to changes to the
total number of scalers overall, right?

So maybe just add a paragraph to the commit message explaining the HQ
stuff a little bit?  I think the code itself should be fine so you can
consider it

Reviewed-by: Matt Roper <matthew.d.roper@intel.com>

after updating the commit message.


Matt

> +			if (!plane) {
> +				struct drm_plane_state *state;
> +				plane = drm_plane_from_index(dev, i);
> +				state = drm_atomic_get_plane_state(drm_state, plane);
> +				if (IS_ERR(state)) {
> +					DRM_DEBUG_KMS("Failed to add [PLANE:%d] to drm_state\n",
> +						plane->base.id);
> +					return PTR_ERR(state);
> +				}
> +			}
> +
> +			intel_plane = to_intel_plane(plane);
> +
> +			/* plane on different crtc cannot be a scaler user of this crtc */
> +			if (WARN_ON(intel_plane->pipe != intel_crtc->pipe)) {
> +				continue;
> +			}
> +
> +			plane_state = to_intel_plane_state(drm_state->plane_states[i]);
> +			scaler_id = &plane_state->scaler_id;
> +		}
> +
> +		if (*scaler_id < 0) {
> +			/* find a free scaler */
> +			for (j = 0; j < intel_crtc->num_scalers; j++) {
> +				if (!scaler_state->scalers[j].in_use) {
> +					scaler_state->scalers[j].in_use = 1;
> +					*scaler_id = scaler_state->scalers[j].id;
> +					DRM_DEBUG_KMS("Attached scaler id %u.%u to %s:%d\n",
> +						intel_crtc->pipe,
> +						i == SKL_CRTC_INDEX ? scaler_state->scaler_id :
> +							plane_state->scaler_id,
> +						i == SKL_CRTC_INDEX ? "CRTC" : "PLANE",
> +						i == SKL_CRTC_INDEX ?  intel_crtc->base.base.id :
> +						plane->base.id);
> +					break;
> +				}
> +			}
> +		}
> +
> +		if (WARN_ON(*scaler_id < 0)) {
> +			DRM_DEBUG_KMS("Cannot find scaler for %s:%d\n",
> +				i == SKL_CRTC_INDEX ? "CRTC" : "PLANE",
> +				i == SKL_CRTC_INDEX ? intel_crtc->base.base.id:plane->base.id);
> +			continue;
> +		}
> +
> +		/* set scaler mode */
> +		scaler_state->scalers[*scaler_id].mode = (num_scalers_need == 1) ?
> +			PS_SCALER_MODE_HQ : PS_SCALER_MODE_DYN;
> +	}
> +
> +	return 0;
> +}
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index f1051f0..9691768 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -5809,6 +5809,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
>  	struct drm_device *dev = crtc->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
> +	int ret;
>  
>  	/* FIXME should check pixel clock limits on all platforms */
>  	if (INTEL_INFO(dev)->gen < 4) {
> @@ -5863,7 +5864,14 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
>  	if (pipe_config->has_pch_encoder)
>  		return ironlake_fdi_compute_config(crtc, pipe_config);
>  
> -	return 0;
> +	/* FIXME: remove below call once atomic mode set is place and all crtc
> +	 * related checks called from atomic_crtc_check function */
> +	ret = 0;
> +	DRM_DEBUG_KMS("intel_crtc = %p drm_state (pipe_config->base.state) = %p\n",
> +		crtc, pipe_config->base.state);
> +	ret = intel_atomic_setup_scalers(dev, crtc, pipe_config);
> +
> +	return ret;
>  }
>  
>  static int skylake_get_display_clock_speed(struct drm_device *dev)
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index adca692..f9614fb 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1382,6 +1382,9 @@ intel_atomic_get_crtc_state(struct drm_atomic_state *state,
>  
>  	return to_intel_crtc_state(crtc_state);
>  }
> +int intel_atomic_setup_scalers(struct drm_device *dev,
> +	struct intel_crtc *intel_crtc,
> +	struct intel_crtc_state *crtc_state);
>  
>  /* intel_atomic_plane.c */
>  struct intel_plane_state *intel_create_plane_state(struct drm_plane *plane);
> -- 
> 1.7.9.5
> 

-- 
Matt Roper
Graphics Software Engineer
IoTG Platform Enabling & Development
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 13/14] drm/i915: skylake primary plane scaling using shared scalers
  2015-04-07 22:28 ` [PATCH 13/14] drm/i915: skylake primary plane scaling " Chandra Konduru
@ 2015-04-09 21:51   ` Matt Roper
  2015-04-09 22:14     ` Konduru, Chandra
  2015-04-13 18:12   ` Daniel Vetter
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 54+ messages in thread
From: Matt Roper @ 2015-04-09 21:51 UTC (permalink / raw)
  To: Chandra Konduru; +Cc: daniel.vetter, intel-gfx, ander.conselvan.de.oliveira

On Tue, Apr 07, 2015 at 03:28:46PM -0700, Chandra Konduru wrote:
> This patch enables skylake primary plane scaling using shared
> scalers atomic desgin.
> 
> v2:
> -use single copy of scaler limits (Matt)
> 
> v3:
> -move detach_scalers to crtc commit path (Matt)
> -use values in plane_state->src as regular integers (me)
> 
> v4:
> -changes to align with updated scaler structures (Matt, me)
> -keep plane src rect in 16.16 format (Matt, Daniel)

See comments on patch #6 that relate to this.  If you want to take the
approach here (perform the unshift in skl_update_plane) then you also
need to do the same for all other platforms (ivb, ilk, vlv, etc.).  But
my suggestion on the other patch (do the unshifting in commit_plane and
leave skl_update_plane alone) might be a bit simpler.


Matt

> 
> Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_atomic.c  |    5 +-
>  drivers/gpu/drm/i915/intel_display.c |   96 ++++++++++++++++++++++++++++++++--
>  drivers/gpu/drm/i915/intel_drv.h     |    1 +
>  drivers/gpu/drm/i915/intel_sprite.c  |    9 ++++
>  4 files changed, 105 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> index 2fc04ec..8f759c6 100644
> --- a/drivers/gpu/drm/i915/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> @@ -167,7 +167,7 @@ int intel_atomic_commit(struct drm_device *dev,
>  		plane->state->state = NULL;
>  	}
>  
> -	/* swap crtc_state */
> +	/* swap crtc_scaler_state */
>  	for (i = 0; i < dev->mode_config.num_crtc; i++) {
>  		struct drm_crtc *crtc = state->crtcs[i];
>  		if (!crtc) {
> @@ -176,6 +176,9 @@ int intel_atomic_commit(struct drm_device *dev,
>  
>  		to_intel_crtc(crtc)->config->scaler_state =
>  			to_intel_crtc_state(state->crtc_states[i])->scaler_state;
> +
> +		if (INTEL_INFO(dev)->gen >= 9)
> +			skl_detach_scalers(to_intel_crtc(crtc));
>  	}
>  
>  	drm_atomic_helper_commit_planes(dev, state);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index aa4da1f..c7ee232 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2978,6 +2978,14 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc,
>  	int pipe = intel_crtc->pipe;
>  	u32 plane_ctl, stride_div;
>  	unsigned long surf_addr;
> +	struct intel_crtc_state *crtc_state = intel_crtc->config;
> +	struct intel_plane_state *plane_state;
> +	int src_x = 0, src_y = 0, src_w = 0, src_h = 0;
> +	int dst_x = 0, dst_y = 0, dst_w = 0, dst_h = 0;
> +	int scaler_id = -1;
> +
> +	plane_state = crtc->primary ?
> +		to_intel_plane_state(crtc->primary->state) : NULL;
>  
>  	if (!intel_crtc->primary_enabled) {
>  		I915_WRITE(PLANE_CTL(pipe, 0), 0);
> @@ -3046,12 +3054,40 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc,
>  					       fb->pixel_format);
>  	surf_addr = intel_plane_obj_offset(to_intel_plane(crtc->primary), obj);
>  
> +	if (plane_state) {
> +		scaler_id = plane_state->scaler_id;
> +		src_x = plane_state->src.x1 >> 16;
> +		src_y = plane_state->src.y1 >> 16;
> +		src_w = drm_rect_width(&plane_state->src) >> 16;
> +		src_h = drm_rect_height(&plane_state->src) >> 16;
> +		dst_x = plane_state->dst.x1;
> +		dst_y = plane_state->dst.y1;
> +		dst_w = drm_rect_width(&plane_state->dst);
> +		dst_h = drm_rect_height(&plane_state->dst);
> +	}
> +
>  	I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
>  	I915_WRITE(PLANE_POS(pipe, 0), 0);
> +
> +	if (src_w && src_h && dst_w && dst_h && scaler_id >= 0) {
> +		uint32_t ps_ctrl = 0;
> +
> +		WARN_ON(x != src_x || y != src_y);
> +		ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(0) |
> +			crtc_state->scaler_state.scalers[scaler_id].mode;
> +		I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
> +		I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
> +		I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (dst_x << 16) | dst_y);
> +		I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id), (dst_w << 16) | dst_h);
> +
> +		I915_WRITE(PLANE_SIZE(pipe, 0), ((src_h - 1) << 16) | (src_w - 1));
> +	} else {
> +		I915_WRITE(PLANE_SIZE(pipe, 0),
> +			(intel_crtc->config->pipe_src_h - 1) << 16 |
> +			(intel_crtc->config->pipe_src_w - 1));
> +	}
> +
>  	I915_WRITE(PLANE_OFFSET(pipe, 0), (y << 16) | x);
> -	I915_WRITE(PLANE_SIZE(pipe, 0),
> -		   (intel_crtc->config->pipe_src_h - 1) << 16 |
> -		   (intel_crtc->config->pipe_src_w - 1));
>  	I915_WRITE(PLANE_STRIDE(pipe, 0), fb->pitches[0] / stride_div);
>  	I915_WRITE(PLANE_SURF(pipe, 0), surf_addr);
>  
> @@ -12778,6 +12814,36 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
>  	}
>  }
>  
> +int
> +skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state)
> +{
> +	int max_scale;
> +	struct drm_device *dev;
> +	struct drm_i915_private *dev_priv;
> +	int crtc_clock, cdclk;
> +
> +	if (!intel_crtc || !crtc_state)
> +		return DRM_PLANE_HELPER_NO_SCALING;
> +
> +	dev = intel_crtc->base.dev;
> +	dev_priv = dev->dev_private;
> +	crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
> +	cdclk = dev_priv->display.get_display_clock_speed(dev);
> +
> +	if (!crtc_clock || !cdclk)
> +		return DRM_PLANE_HELPER_NO_SCALING;
> +
> +	/*
> +	 * skl max scale is lower of:
> +	 *    close to 3 but not 3, -1 is for that purpose
> +	 *            or
> +	 *    cdclk/crtc_clock
> +	 */
> +	max_scale = min((1 << 16) * 3 - 1, (1 << 8) * ((cdclk << 8) / crtc_clock));
> +
> +	return max_scale;
> +}
> +
>  static int
>  intel_check_primary_plane(struct drm_plane *plane,
>  			  struct intel_plane_state *state)
> @@ -12786,19 +12852,29 @@ intel_check_primary_plane(struct drm_plane *plane,
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct drm_crtc *crtc = state->base.crtc;
>  	struct intel_crtc *intel_crtc;
> +	struct intel_crtc_state *crtc_state;
>  	struct drm_framebuffer *fb = state->base.fb;
>  	struct drm_rect *dest = &state->dst;
>  	struct drm_rect *src = &state->src;
>  	const struct drm_rect *clip = &state->clip;
> +	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
> +	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
>  	int ret;
>  
>  	crtc = crtc ? crtc : plane->crtc;
>  	intel_crtc = to_intel_crtc(crtc);
> +	crtc_state = state->base.state ?
> +		intel_atomic_get_crtc_state(state->base.state, intel_crtc) : NULL;
> +
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		min_scale = 1;
> +		max_scale = skl_max_scale(intel_crtc, crtc_state);
> +	}
>  
>  	ret = drm_plane_helper_check_update(plane, crtc, fb,
>  					    src, dest, clip,
> -					    DRM_PLANE_HELPER_NO_SCALING,
> -					    DRM_PLANE_HELPER_NO_SCALING,
> +					    min_scale,
> +					    max_scale,
>  					    false, true, &state->visible);
>  	if (ret)
>  		return ret;
> @@ -12842,6 +12918,13 @@ intel_check_primary_plane(struct drm_plane *plane,
>  			intel_crtc->atomic.update_wm = true;
>  	}
>  
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		ret = skl_update_scaler_users(intel_crtc, crtc_state,
> +			to_intel_plane(plane), state, 0);
> +		if (ret)
> +			return ret;
> +	}
> +
>  	return 0;
>  }
>  
> @@ -13021,6 +13104,9 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
>  
>  	primary->can_scale = false;
>  	primary->max_downscale = 1;
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		primary->can_scale = true;
> +	}
>  	state->scaler_id = -1;
>  	primary->pipe = pipe;
>  	primary->plane = pipe;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 7b28bff..0543150 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1125,6 +1125,7 @@ void skl_detach_scalers(struct intel_crtc *intel_crtc);
>  int skl_update_scaler_users(struct intel_crtc *intel_crtc,
>  	struct intel_crtc_state *crtc_state, struct intel_plane *intel_plane,
>  	struct intel_plane_state *plane_state, int force_detach);
> +int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state);
>  
>  unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
>  				     struct drm_i915_gem_object *obj);
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index c05fb36..955965c 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -1119,6 +1119,15 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
>  	}
>  
>  	intel_plane = to_intel_plane(plane);
> +
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		/* plane scaling and colorkey are mutually exclusive */
> +		if (to_intel_plane_state(plane->state)->scaler_id >= 0) {
> +			DRM_ERROR("colorkey not allowed with scaler\n");
> +			return -EINVAL;
> +		}
> +	}
> +
>  	intel_plane->ckey = *set;
>  
>  	/*
> -- 
> 1.7.9.5
> 

-- 
Matt Roper
Graphics Software Engineer
IoTG Platform Enabling & Development
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 00/14] skylake display scalers
  2015-04-07 22:28 [PATCH 00/14] skylake display scalers Chandra Konduru
                   ` (13 preceding siblings ...)
  2015-04-07 22:28 ` [PATCH 14/14] drm/i915: skylake sprite " Chandra Konduru
@ 2015-04-09 21:53 ` Matt Roper
  2015-04-09 22:12   ` Matt Roper
  2015-04-10  9:34 ` Daniel Vetter
  15 siblings, 1 reply; 54+ messages in thread
From: Matt Roper @ 2015-04-09 21:53 UTC (permalink / raw)
  To: Chandra Konduru; +Cc: daniel.vetter, intel-gfx, ander.conselvan.de.oliveira

On Tue, Apr 07, 2015 at 03:28:33PM -0700, Chandra Konduru wrote:
> Primary changes in this version are:
> 1) Moved num_scalers to crtc
> 2) Changed src/dst rect ranges to #defines
> 3) Dropped scaling ratios from state instead calculating when needed
> 4) Dropped filter from scaler
> 5) Squashed helper functions from standalone patches into patch where 1st used
> 6) Kept sprite src tect in 16.16 format
> 
> Though changes are minor but they got sprinkled into multiple patches.
> 
> Sending full patch series for completeness. Individual patch headers
> have additional details on changes. This series should cleanly
> merge to latest drm-intel-nighly.

Okay, this is looking pretty good now.  I only spotted a single issue
(which affects patches #6 and #13); all of the other patches are

Reviewed-by: Matt Roper <matthew.d.roper@intel.com>

I also requested an update to the commit message of patch #9, but the
code itself looks fine and still has my r-b.


Matt

> 
> Chandra Konduru (14):
>   drm: Adding drm helper function drm_plane_from_index().
>   drm/i915: Register definitions for skylake scalers
>   drm/i915: skylake scaler structure definitions
>   drm/i915: Initialize plane colorkey to NONE
>   drm/i915: Initialize skylake scalers
>   drm/i915: Keep sprite plane src rect in 16.16 format
>   drm/i915: Dump scaler_state too as part of dumping crtc_state
>   drm/i915: Preserve scaler state when clearing crtc_state
>   drm/i915: setup scalers for crtc_compute_config
>   drm/i915: Ensure setting up scalers into staged crtc_state
>   drm/i915: copy staged scaler state from drm state to crtc->config.
>   drm/i915: skylake panel fitting using shared scalers
>   drm/i915: skylake primary plane scaling using shared scalers
>   drm/i915: skylake sprite plane scaling using shared scalers
> 
>  drivers/gpu/drm/drm_crtc.c           |   22 ++
>  drivers/gpu/drm/i915/i915_reg.h      |  115 +++++++++
>  drivers/gpu/drm/i915/intel_atomic.c  |  163 +++++++++++++
>  drivers/gpu/drm/i915/intel_display.c |  441 +++++++++++++++++++++++++++++++---
>  drivers/gpu/drm/i915/intel_dp.c      |    8 +
>  drivers/gpu/drm/i915/intel_drv.h     |   76 ++++++
>  drivers/gpu/drm/i915/intel_sprite.c  |   83 +++++--
>  include/drm/drm_crtc.h               |    1 +
>  8 files changed, 855 insertions(+), 54 deletions(-)
> 
> -- 
> 1.7.9.5
> 

-- 
Matt Roper
Graphics Software Engineer
IoTG Platform Enabling & Development
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 09/14] drm/i915: setup scalers for crtc_compute_config
  2015-04-09 21:51   ` Matt Roper
@ 2015-04-09 22:07     ` Konduru, Chandra
  0 siblings, 0 replies; 54+ messages in thread
From: Konduru, Chandra @ 2015-04-09 22:07 UTC (permalink / raw)
  To: Roper, Matthew D; +Cc: Vetter, Daniel, intel-gfx, Conselvan De Oliveira, Ander



> -----Original Message-----
> From: Roper, Matthew D
> Sent: Thursday, April 09, 2015 2:51 PM
> To: Konduru, Chandra
> Cc: intel-gfx@lists.freedesktop.org; Vetter, Daniel; Conselvan De Oliveira, Ander
> Subject: Re: [PATCH 09/14] drm/i915: setup scalers for crtc_compute_config
> 
> On Tue, Apr 07, 2015 at 03:28:42PM -0700, Chandra Konduru wrote:
> > Added intel_atomic_setup_scalers to setup scalers based on staged
> > scaling requests from a crtc and its planes. If staged requests are
> > supportable, this function assigns scalers to requested planes and
> > crtc. Note that the scaler assignement itself is staged into
> > crtc_state and respective plane_states for later commit after all
> > checks have been done.
> >
> > overall high level flow:
> >  - scaler requests are staged into crtc_state by planes/crtc
> >  - check whether staged scaling requests can be supported
> >  - add planes using scalers that aren't in current transaction
> >  - assign scalers to requested users
> >  - as part of plane commit, scalers will be committed
> >    (i.e., either attached or detached) to respective planes in hw
> >  - as part of crtc_commit, scaler will be either attached or detached
> >    to crtc in hw
> >
> > crtc_compute_config calls intel_atomic_setup_scalers() to start scaler
> > assignments as per scaler state in crtc config. This call should be
> > moved to atomic crtc once it is available.
> >
> > v2:
> > -removed a log message (me)
> > -changed input parameter to crtc_state (me)
> >
> > v3:
> > -remove assigning plane_state returned by drm_atomic_get_plane_state
> > (Matt) -fail if there is an error from drm_atomic_get_plane_state
> > (Matt)
> >
> > v4:
> > -changes to align with updated scaler structure (Matt, me)
> >
> > Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_atomic.c  |  137
> ++++++++++++++++++++++++++++++++++
> >  drivers/gpu/drm/i915/intel_display.c |   10 ++-
> >  drivers/gpu/drm/i915/intel_drv.h     |    3 +
> >  3 files changed, 149 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_atomic.c
> > b/drivers/gpu/drm/i915/intel_atomic.c
> > index 3903b90..ac317b4 100644
> > --- a/drivers/gpu/drm/i915/intel_atomic.c
> > +++ b/drivers/gpu/drm/i915/intel_atomic.c
> > @@ -241,3 +241,140 @@ intel_crtc_destroy_state(struct drm_crtc *crtc,
> > {
> >  	drm_atomic_helper_crtc_destroy_state(crtc, state);  }
> > +
> > +/**
> > + * intel_atomic_setup_scalers() - setup scalers for crtc per staged
> > +requests
> > + * @dev: DRM device
> > + * @crtc: intel crtc
> > + * @crtc_state: incoming crtc_state to validate and setup scalers
> > + *
> > + * This function sets up scalers based on staged scaling requests for
> > + * a @crtc and its planes. It is called from crtc level check path.
> > +If request
> > + * is a supportable request, it attaches scalers to requested planes and crtc.
> > + *
> > + * This function takes into account the current scaler(s) in use by
> > +any planes
> > + * not being part of this atomic state
> > + *
> > + *  Returns:
> > + *         0 - scalers were setup succesfully
> > + *         error code - otherwise
> > + */
> > +int intel_atomic_setup_scalers(struct drm_device *dev,
> > +	struct intel_crtc *intel_crtc,
> > +	struct intel_crtc_state *crtc_state) {
> > +	struct drm_plane *plane = NULL;
> > +	struct intel_plane *intel_plane;
> > +	struct intel_plane_state *plane_state = NULL;
> > +	struct intel_crtc_scaler_state *scaler_state;
> > +	struct drm_atomic_state *drm_state;
> > +	int num_scalers_need;
> > +	int i, j;
> > +
> > +	if (INTEL_INFO(dev)->gen < 9 || !intel_crtc || !crtc_state)
> > +		return 0;
> > +
> > +	scaler_state = &crtc_state->scaler_state;
> > +	drm_state = crtc_state->base.state;
> > +
> > +	num_scalers_need = hweight32(scaler_state->scaler_users);
> > +	DRM_DEBUG_KMS("crtc_state = %p need = %d avail = %d scaler_users =
> 0x%x\n",
> > +		crtc_state, num_scalers_need, intel_crtc->num_scalers,
> > +		scaler_state->scaler_users);
> > +
> > +	/*
> > +	 * High level flow:
> > +	 * - staged scaler requests are already in scaler_state->scaler_users
> > +	 * - check whether staged scaling requests can be supported
> > +	 * - add planes using scalers that aren't in current transaction
> > +	 * - assign scalers to requested users
> > +	 * - as part of plane commit, scalers will be committed
> > +	 *   (i.e., either attached or detached) to respective planes in hw
> > +	 * - as part of crtc_commit, scaler will be either attached or detached
> > +	 *   to crtc in hw
> > +	 */
> > +
> > +	/* fail if required scalers > available scalers */
> > +	if (num_scalers_need > intel_crtc->num_scalers){
> > +		DRM_DEBUG_KMS("Too many scaling requests %d > %d\n",
> > +			num_scalers_need, intel_crtc->num_scalers);
> > +		return -EINVAL;
> > +	}
> > +
> > +	/* walkthrough scaler_users bits and start assigning scalers */
> > +	for (i = 0; i < sizeof(scaler_state->scaler_users) * 8; i++) {
> > +		int *scaler_id;
> > +
> > +		/* skip if scaler not required */
> > +		if (!(scaler_state->scaler_users & (1 << i)))
> > +			continue;
> > +
> > +		if (i == SKL_CRTC_INDEX) {
> > +			/* panel fitter case: assign as a crtc scaler */
> > +			scaler_id = &scaler_state->scaler_id;
> > +		} else {
> > +			if (!drm_state)
> > +				continue;
> > +
> > +			/* plane scaler case: assign as a plane scaler */
> > +			/* find the plane that set the bit as scaler_user */
> > +			plane = drm_state->planes[i];
> > +
> > +			/*
> > +			 * to enable/disable hq mode, add planes that are using
> scaler
> > +			 * into this transaction
> > +			 */
> 
> The code here looks fine, but the reference to "hq mode" kind of comes out of
> the blue.  I realize you're setting HQ or DYN down at the bottom of this function,
> but there's never really any indication of what those are or what they mean (or
> how having the other plane states in the top-level transaction relates to HQ
> mode).  I'm assuming what your comment here is trying to say is that the mode
> for an already setup and unchanged plane+scaler might have to change due to
> changes to the total number of scalers overall, right?
> 
> So maybe just add a paragraph to the commit message explaining the HQ stuff a
> little bit?  I think the code itself should be fine so you can consider it
> 
> Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
> 
> after updating the commit message.
OK
> 
> 
> Matt
> 
> > +			if (!plane) {
> > +				struct drm_plane_state *state;
> > +				plane = drm_plane_from_index(dev, i);
> > +				state =
> drm_atomic_get_plane_state(drm_state, plane);
> > +				if (IS_ERR(state)) {
> > +					DRM_DEBUG_KMS("Failed to add
> [PLANE:%d] to drm_state\n",
> > +						plane->base.id);
> > +					return PTR_ERR(state);
> > +				}
> > +			}
> > +
> > +			intel_plane = to_intel_plane(plane);
> > +
> > +			/* plane on different crtc cannot be a scaler user of this
> crtc */
> > +			if (WARN_ON(intel_plane->pipe != intel_crtc->pipe)) {
> > +				continue;
> > +			}
> > +
> > +			plane_state = to_intel_plane_state(drm_state-
> >plane_states[i]);
> > +			scaler_id = &plane_state->scaler_id;
> > +		}
> > +
> > +		if (*scaler_id < 0) {
> > +			/* find a free scaler */
> > +			for (j = 0; j < intel_crtc->num_scalers; j++) {
> > +				if (!scaler_state->scalers[j].in_use) {
> > +					scaler_state->scalers[j].in_use = 1;
> > +					*scaler_id = scaler_state->scalers[j].id;
> > +					DRM_DEBUG_KMS("Attached scaler id
> %u.%u to %s:%d\n",
> > +						intel_crtc->pipe,
> > +						i == SKL_CRTC_INDEX ?
> scaler_state->scaler_id :
> > +							plane_state-
> >scaler_id,
> > +						i == SKL_CRTC_INDEX ? "CRTC"
> : "PLANE",
> > +						i == SKL_CRTC_INDEX ?
> intel_crtc->base.base.id :
> > +						plane->base.id);
> > +					break;
> > +				}
> > +			}
> > +		}
> > +
> > +		if (WARN_ON(*scaler_id < 0)) {
> > +			DRM_DEBUG_KMS("Cannot find scaler for %s:%d\n",
> > +				i == SKL_CRTC_INDEX ? "CRTC" : "PLANE",
> > +				i == SKL_CRTC_INDEX ? intel_crtc-
> >base.base.id:plane->base.id);
> > +			continue;
> > +		}
> > +
> > +		/* set scaler mode */
> > +		scaler_state->scalers[*scaler_id].mode = (num_scalers_need ==
> 1) ?
> > +			PS_SCALER_MODE_HQ : PS_SCALER_MODE_DYN;
> > +	}
> > +
> > +	return 0;
> > +}
> > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > b/drivers/gpu/drm/i915/intel_display.c
> > index f1051f0..9691768 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -5809,6 +5809,7 @@ static int intel_crtc_compute_config(struct
> intel_crtc *crtc,
> >  	struct drm_device *dev = crtc->base.dev;
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> >  	struct drm_display_mode *adjusted_mode =
> > &pipe_config->base.adjusted_mode;
> > +	int ret;
> >
> >  	/* FIXME should check pixel clock limits on all platforms */
> >  	if (INTEL_INFO(dev)->gen < 4) {
> > @@ -5863,7 +5864,14 @@ static int intel_crtc_compute_config(struct
> intel_crtc *crtc,
> >  	if (pipe_config->has_pch_encoder)
> >  		return ironlake_fdi_compute_config(crtc, pipe_config);
> >
> > -	return 0;
> > +	/* FIXME: remove below call once atomic mode set is place and all crtc
> > +	 * related checks called from atomic_crtc_check function */
> > +	ret = 0;
> > +	DRM_DEBUG_KMS("intel_crtc = %p drm_state (pipe_config-
> >base.state) = %p\n",
> > +		crtc, pipe_config->base.state);
> > +	ret = intel_atomic_setup_scalers(dev, crtc, pipe_config);
> > +
> > +	return ret;
> >  }
> >
> >  static int skylake_get_display_clock_speed(struct drm_device *dev)
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h
> > b/drivers/gpu/drm/i915/intel_drv.h
> > index adca692..f9614fb 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -1382,6 +1382,9 @@ intel_atomic_get_crtc_state(struct
> > drm_atomic_state *state,
> >
> >  	return to_intel_crtc_state(crtc_state);  }
> > +int intel_atomic_setup_scalers(struct drm_device *dev,
> > +	struct intel_crtc *intel_crtc,
> > +	struct intel_crtc_state *crtc_state);
> >
> >  /* intel_atomic_plane.c */
> >  struct intel_plane_state *intel_create_plane_state(struct drm_plane
> > *plane);
> > --
> > 1.7.9.5
> >
> 
> --
> Matt Roper
> Graphics Software Engineer
> IoTG Platform Enabling & Development
> Intel Corporation
> (916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 06/14] drm/i915: Keep sprite plane src rect in 16.16 format
  2015-04-09 21:50   ` Matt Roper
@ 2015-04-09 22:08     ` Konduru, Chandra
  2015-04-09 22:22       ` Matt Roper
  0 siblings, 1 reply; 54+ messages in thread
From: Konduru, Chandra @ 2015-04-09 22:08 UTC (permalink / raw)
  To: Roper, Matthew D; +Cc: Vetter, Daniel, intel-gfx, Conselvan De Oliveira, Ander



> -----Original Message-----
> From: Roper, Matthew D
> Sent: Thursday, April 09, 2015 2:51 PM
> To: Konduru, Chandra
> Cc: intel-gfx@lists.freedesktop.org; Vetter, Daniel; Conselvan De Oliveira, Ander
> Subject: Re: [PATCH 06/14] drm/i915: Keep sprite plane src rect in 16.16 format
> 
> On Tue, Apr 07, 2015 at 03:28:39PM -0700, Chandra Konduru wrote:
> > This patch keeps intel_plane_state->src rect back into 16.16 format.
> >
> > v2:
> > -sprite src rect to match primary format (Matt, Daniel)
> >
> > Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
> 
> This looks good, and matches what we had discussed, but don't you also need to
> add the corresponding unshift in intel_commit_sprite_plane() when we actually
> pull the values out and make use of them?  
The unshift is in patch #14 which should have been in this patch.

From #14 relevant hunk is:
@@ -1081,10 +1122,10 @@ intel_commit_sprite_plane(struct drm_plane *plane,
            crtc_y = state->dst.y1;
            crtc_w = drm_rect_width(&state->dst);
            crtc_h = drm_rect_height(&state->dst);
-           src_x = state->src.x1;
-           src_y = state->src.y1;
-           src_w = drm_rect_width(&state->src);
-           src_h = drm_rect_height(&state->src);
+           src_x = state->src.x1 >> 16;
+           src_y = state->src.y1 >> 16;
+           src_w = drm_rect_width(&state->src) >> 16;
+           src_h = drm_rect_height(&state->src) >> 16;
            intel_plane->update_plane(plane, crtc, fb,
                          crtc_x, crtc_y, crtc_w, crtc_h,
                          src_x, src_y, src_w, src_h);

> The goal is to keep the meaning of
> the structure fields consistent at all times
> (16.16 fixed pt), but once we pull the values out of the structure, we wind up
> passing them to functions that doing use fixed point, so we do need to unshift at
> that point.
> 
> It looks like in patch #13 you do switch the low-level
> skl_update_plane() to make use of 16.16 input parameters.  However any
> commit that we bisect through between #6 and #13 is going to wind up treating
> 16.16 values as integer values, which I assume will blow up.
Patch #13 doesn't touches skl_update_plane(). Perhaps you may be referring to #14.
In #14, it does unshift as I mentioned above. I think I need to move above hunk
to #6 to fix any potential issue due to bisect.

Let me know if you see any potential issue after moving the above hunk to #6.

> Also, you haven't touched any of the other platforms (ilk, vlv, ivb,
> etc.) so they're all still going to have problems.
Shifting and unshifting is happening in intel_check_plane and intel_commit_plane
which is common for all platforms. I don't see what the problem you
are referring to?
> 
> I think the easiest short-term solution is to do the unshifting in commit_plane
> and leave the hardware-specific programming functions as-is.  
This is what I'm doing now keeping platform_update_plane(parameters) use
unshifted values (i.e., regular ints). I don't see any value to pass function parameters
as 16.16 values. If there is a need arise we can change the semantics of parameters
at a later time. 

> Longer term,
> maybe it makes sense for a future patchset to change the actual register-
> programming functions (foo_update_plane) so that they take a plane_state
> directly and do their own unshifting?  In that case we'd need to update them to
> do their own unshifting, but at least we wouldn't have to pull all the values out in
> commit_plane, just to pass them to these functions.
> 
> 
> Matt
> 
> > ---
> >  drivers/gpu/drm/i915/intel_sprite.c |    8 ++++----
> >  1 file changed, 4 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_sprite.c
> > b/drivers/gpu/drm/i915/intel_sprite.c
> > index ac4aa68..c05fb36 100644
> > --- a/drivers/gpu/drm/i915/intel_sprite.c
> > +++ b/drivers/gpu/drm/i915/intel_sprite.c
> > @@ -1006,10 +1006,10 @@ intel_check_sprite_plane(struct drm_plane
> *plane,
> >  	}
> >
> >  	if (state->visible) {
> > -		src->x1 = src_x;
> > -		src->x2 = src_x + src_w;
> > -		src->y1 = src_y;
> > -		src->y2 = src_y + src_h;
> > +		src->x1 = src_x << 16;
> > +		src->x2 = (src_x + src_w) << 16;
> > +		src->y1 = src_y << 16;
> > +		src->y2 = (src_y + src_h) << 16;
> >  	}
> >
> >  	dst->x1 = crtc_x;
> > --
> > 1.7.9.5
> >
> 
> --
> Matt Roper
> Graphics Software Engineer
> IoTG Platform Enabling & Development
> Intel Corporation
> (916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 00/14] skylake display scalers
  2015-04-09 21:53 ` [PATCH 00/14] skylake display scalers Matt Roper
@ 2015-04-09 22:12   ` Matt Roper
  2015-04-09 22:22     ` Konduru, Chandra
  0 siblings, 1 reply; 54+ messages in thread
From: Matt Roper @ 2015-04-09 22:12 UTC (permalink / raw)
  To: Chandra Konduru; +Cc: daniel.vetter, intel-gfx, ander.conselvan.de.oliveira

On Thu, Apr 09, 2015 at 02:53:38PM -0700, Matt Roper wrote:
> On Tue, Apr 07, 2015 at 03:28:33PM -0700, Chandra Konduru wrote:
> > Primary changes in this version are:
> > 1) Moved num_scalers to crtc
> > 2) Changed src/dst rect ranges to #defines
> > 3) Dropped scaling ratios from state instead calculating when needed
> > 4) Dropped filter from scaler
> > 5) Squashed helper functions from standalone patches into patch where 1st used
> > 6) Kept sprite src tect in 16.16 format
> > 
> > Though changes are minor but they got sprinkled into multiple patches.
> > 
> > Sending full patch series for completeness. Individual patch headers
> > have additional details on changes. This series should cleanly
> > merge to latest drm-intel-nighly.
> 
> Okay, this is looking pretty good now.  I only spotted a single issue
> (which affects patches #6 and #13); all of the other patches are
> 
> Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
> 
> I also requested an update to the commit message of patch #9, but the
> code itself looks fine and still has my r-b.

Oh, one thing I forgot to mention.  My understanding is that while we're
on transitional plane helpers, your scaler setup code still isn't going
to get run properly for legacy SetPlane ioctl calls (correct me if I'm
wrong and overlooked a change related to that).  I know Maarten is
working on addressing the issues with the full atomic helpers properly,
but I also have a bit of a workaround patch that might be useful in the
time being here:

        http://patchwork.freedesktop.org/patch/46773/

Do you think we need to make sure we're switched back to the full atomic
helpers via one of those solutions before merging your series here?


Matt

> 
> 
> Matt
> 
> > 
> > Chandra Konduru (14):
> >   drm: Adding drm helper function drm_plane_from_index().
> >   drm/i915: Register definitions for skylake scalers
> >   drm/i915: skylake scaler structure definitions
> >   drm/i915: Initialize plane colorkey to NONE
> >   drm/i915: Initialize skylake scalers
> >   drm/i915: Keep sprite plane src rect in 16.16 format
> >   drm/i915: Dump scaler_state too as part of dumping crtc_state
> >   drm/i915: Preserve scaler state when clearing crtc_state
> >   drm/i915: setup scalers for crtc_compute_config
> >   drm/i915: Ensure setting up scalers into staged crtc_state
> >   drm/i915: copy staged scaler state from drm state to crtc->config.
> >   drm/i915: skylake panel fitting using shared scalers
> >   drm/i915: skylake primary plane scaling using shared scalers
> >   drm/i915: skylake sprite plane scaling using shared scalers
> > 
> >  drivers/gpu/drm/drm_crtc.c           |   22 ++
> >  drivers/gpu/drm/i915/i915_reg.h      |  115 +++++++++
> >  drivers/gpu/drm/i915/intel_atomic.c  |  163 +++++++++++++
> >  drivers/gpu/drm/i915/intel_display.c |  441 +++++++++++++++++++++++++++++++---
> >  drivers/gpu/drm/i915/intel_dp.c      |    8 +
> >  drivers/gpu/drm/i915/intel_drv.h     |   76 ++++++
> >  drivers/gpu/drm/i915/intel_sprite.c  |   83 +++++--
> >  include/drm/drm_crtc.h               |    1 +
> >  8 files changed, 855 insertions(+), 54 deletions(-)
> > 
> > -- 
> > 1.7.9.5
> > 
> 
> -- 
> Matt Roper
> Graphics Software Engineer
> IoTG Platform Enabling & Development
> Intel Corporation
> (916) 356-2795

-- 
Matt Roper
Graphics Software Engineer
IoTG Platform Enabling & Development
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 13/14] drm/i915: skylake primary plane scaling using shared scalers
  2015-04-09 21:51   ` Matt Roper
@ 2015-04-09 22:14     ` Konduru, Chandra
  2015-04-13  9:46       ` Daniel Vetter
  0 siblings, 1 reply; 54+ messages in thread
From: Konduru, Chandra @ 2015-04-09 22:14 UTC (permalink / raw)
  To: Roper, Matthew D; +Cc: Vetter, Daniel, intel-gfx, Conselvan De Oliveira, Ander



> -----Original Message-----
> From: Roper, Matthew D
> Sent: Thursday, April 09, 2015 2:52 PM
> To: Konduru, Chandra
> Cc: intel-gfx@lists.freedesktop.org; Vetter, Daniel; Conselvan De Oliveira, Ander
> Subject: Re: [PATCH 13/14] drm/i915: skylake primary plane scaling using shared
> scalers
> 
> On Tue, Apr 07, 2015 at 03:28:46PM -0700, Chandra Konduru wrote:
> > This patch enables skylake primary plane scaling using shared scalers
> > atomic desgin.
> >
> > v2:
> > -use single copy of scaler limits (Matt)
> >
> > v3:
> > -move detach_scalers to crtc commit path (Matt) -use values in
> > plane_state->src as regular integers (me)
> >
> > v4:
> > -changes to align with updated scaler structures (Matt, me) -keep
> > plane src rect in 16.16 format (Matt, Daniel)
> 
> See comments on patch #6 that relate to this.  If you want to take the approach
> here (perform the unshift in skl_update_plane) then you also need to do the
> same for all other platforms (ivb, ilk, vlv, etc.).  But my suggestion on the other
> patch (do the unshifting in commit_plane and leave skl_update_plane alone)
> might be a bit simpler.

Above v4: comment is saying that the change done in v3 was undone to keep 
primary_plane src rect in 16.16 format.

As I responded to your patch #6 comment, moving unshift hunk (which is for
sprite plane) from #14 to #6 will avoid any potential bisect issue that you mentioned.

For other than skylake, primary planes platform level update functions doesn't use
src_rect instead operate based on passed parameters which are in regular ints.
Only for skylake primary plane update function, src rect is used for windowing,
scaling purposes.

> 
> 
> Matt
> 
> >
> > Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_atomic.c  |    5 +-
> >  drivers/gpu/drm/i915/intel_display.c |   96
> ++++++++++++++++++++++++++++++++--
> >  drivers/gpu/drm/i915/intel_drv.h     |    1 +
> >  drivers/gpu/drm/i915/intel_sprite.c  |    9 ++++
> >  4 files changed, 105 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_atomic.c
> > b/drivers/gpu/drm/i915/intel_atomic.c
> > index 2fc04ec..8f759c6 100644
> > --- a/drivers/gpu/drm/i915/intel_atomic.c
> > +++ b/drivers/gpu/drm/i915/intel_atomic.c
> > @@ -167,7 +167,7 @@ int intel_atomic_commit(struct drm_device *dev,
> >  		plane->state->state = NULL;
> >  	}
> >
> > -	/* swap crtc_state */
> > +	/* swap crtc_scaler_state */
> >  	for (i = 0; i < dev->mode_config.num_crtc; i++) {
> >  		struct drm_crtc *crtc = state->crtcs[i];
> >  		if (!crtc) {
> > @@ -176,6 +176,9 @@ int intel_atomic_commit(struct drm_device *dev,
> >
> >  		to_intel_crtc(crtc)->config->scaler_state =
> >  			to_intel_crtc_state(state->crtc_states[i])->scaler_state;
> > +
> > +		if (INTEL_INFO(dev)->gen >= 9)
> > +			skl_detach_scalers(to_intel_crtc(crtc));
> >  	}
> >
> >  	drm_atomic_helper_commit_planes(dev, state); diff --git
> > a/drivers/gpu/drm/i915/intel_display.c
> > b/drivers/gpu/drm/i915/intel_display.c
> > index aa4da1f..c7ee232 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -2978,6 +2978,14 @@ static void skylake_update_primary_plane(struct
> drm_crtc *crtc,
> >  	int pipe = intel_crtc->pipe;
> >  	u32 plane_ctl, stride_div;
> >  	unsigned long surf_addr;
> > +	struct intel_crtc_state *crtc_state = intel_crtc->config;
> > +	struct intel_plane_state *plane_state;
> > +	int src_x = 0, src_y = 0, src_w = 0, src_h = 0;
> > +	int dst_x = 0, dst_y = 0, dst_w = 0, dst_h = 0;
> > +	int scaler_id = -1;
> > +
> > +	plane_state = crtc->primary ?
> > +		to_intel_plane_state(crtc->primary->state) : NULL;
> >
> >  	if (!intel_crtc->primary_enabled) {
> >  		I915_WRITE(PLANE_CTL(pipe, 0), 0);
> > @@ -3046,12 +3054,40 @@ static void skylake_update_primary_plane(struct
> drm_crtc *crtc,
> >  					       fb->pixel_format);
> >  	surf_addr = intel_plane_obj_offset(to_intel_plane(crtc->primary),
> > obj);
> >
> > +	if (plane_state) {
> > +		scaler_id = plane_state->scaler_id;
> > +		src_x = plane_state->src.x1 >> 16;
> > +		src_y = plane_state->src.y1 >> 16;
> > +		src_w = drm_rect_width(&plane_state->src) >> 16;
> > +		src_h = drm_rect_height(&plane_state->src) >> 16;
> > +		dst_x = plane_state->dst.x1;
> > +		dst_y = plane_state->dst.y1;
> > +		dst_w = drm_rect_width(&plane_state->dst);
> > +		dst_h = drm_rect_height(&plane_state->dst);
> > +	}
> > +
> >  	I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
> >  	I915_WRITE(PLANE_POS(pipe, 0), 0);
> > +
> > +	if (src_w && src_h && dst_w && dst_h && scaler_id >= 0) {
> > +		uint32_t ps_ctrl = 0;
> > +
> > +		WARN_ON(x != src_x || y != src_y);
> > +		ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(0) |
> > +			crtc_state->scaler_state.scalers[scaler_id].mode;
> > +		I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
> > +		I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
> > +		I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (dst_x << 16) |
> dst_y);
> > +		I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id), (dst_w << 16) |
> dst_h);
> > +
> > +		I915_WRITE(PLANE_SIZE(pipe, 0), ((src_h - 1) << 16) | (src_w -
> 1));
> > +	} else {
> > +		I915_WRITE(PLANE_SIZE(pipe, 0),
> > +			(intel_crtc->config->pipe_src_h - 1) << 16 |
> > +			(intel_crtc->config->pipe_src_w - 1));
> > +	}
> > +
> >  	I915_WRITE(PLANE_OFFSET(pipe, 0), (y << 16) | x);
> > -	I915_WRITE(PLANE_SIZE(pipe, 0),
> > -		   (intel_crtc->config->pipe_src_h - 1) << 16 |
> > -		   (intel_crtc->config->pipe_src_w - 1));
> >  	I915_WRITE(PLANE_STRIDE(pipe, 0), fb->pitches[0] / stride_div);
> >  	I915_WRITE(PLANE_SURF(pipe, 0), surf_addr);
> >
> > @@ -12778,6 +12814,36 @@ intel_cleanup_plane_fb(struct drm_plane
> *plane,
> >  	}
> >  }
> >
> > +int
> > +skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state
> > +*crtc_state) {
> > +	int max_scale;
> > +	struct drm_device *dev;
> > +	struct drm_i915_private *dev_priv;
> > +	int crtc_clock, cdclk;
> > +
> > +	if (!intel_crtc || !crtc_state)
> > +		return DRM_PLANE_HELPER_NO_SCALING;
> > +
> > +	dev = intel_crtc->base.dev;
> > +	dev_priv = dev->dev_private;
> > +	crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
> > +	cdclk = dev_priv->display.get_display_clock_speed(dev);
> > +
> > +	if (!crtc_clock || !cdclk)
> > +		return DRM_PLANE_HELPER_NO_SCALING;
> > +
> > +	/*
> > +	 * skl max scale is lower of:
> > +	 *    close to 3 but not 3, -1 is for that purpose
> > +	 *            or
> > +	 *    cdclk/crtc_clock
> > +	 */
> > +	max_scale = min((1 << 16) * 3 - 1, (1 << 8) * ((cdclk << 8) /
> > +crtc_clock));
> > +
> > +	return max_scale;
> > +}
> > +
> >  static int
> >  intel_check_primary_plane(struct drm_plane *plane,
> >  			  struct intel_plane_state *state) @@ -12786,19
> +12852,29 @@
> > intel_check_primary_plane(struct drm_plane *plane,
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> >  	struct drm_crtc *crtc = state->base.crtc;
> >  	struct intel_crtc *intel_crtc;
> > +	struct intel_crtc_state *crtc_state;
> >  	struct drm_framebuffer *fb = state->base.fb;
> >  	struct drm_rect *dest = &state->dst;
> >  	struct drm_rect *src = &state->src;
> >  	const struct drm_rect *clip = &state->clip;
> > +	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
> > +	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
> >  	int ret;
> >
> >  	crtc = crtc ? crtc : plane->crtc;
> >  	intel_crtc = to_intel_crtc(crtc);
> > +	crtc_state = state->base.state ?
> > +		intel_atomic_get_crtc_state(state->base.state, intel_crtc) :
> NULL;
> > +
> > +	if (INTEL_INFO(dev)->gen >= 9) {
> > +		min_scale = 1;
> > +		max_scale = skl_max_scale(intel_crtc, crtc_state);
> > +	}
> >
> >  	ret = drm_plane_helper_check_update(plane, crtc, fb,
> >  					    src, dest, clip,
> > -					    DRM_PLANE_HELPER_NO_SCALING,
> > -					    DRM_PLANE_HELPER_NO_SCALING,
> > +					    min_scale,
> > +					    max_scale,
> >  					    false, true, &state->visible);
> >  	if (ret)
> >  		return ret;
> > @@ -12842,6 +12918,13 @@ intel_check_primary_plane(struct drm_plane
> *plane,
> >  			intel_crtc->atomic.update_wm = true;
> >  	}
> >
> > +	if (INTEL_INFO(dev)->gen >= 9) {
> > +		ret = skl_update_scaler_users(intel_crtc, crtc_state,
> > +			to_intel_plane(plane), state, 0);
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> >  	return 0;
> >  }
> >
> > @@ -13021,6 +13104,9 @@ static struct drm_plane
> > *intel_primary_plane_create(struct drm_device *dev,
> >
> >  	primary->can_scale = false;
> >  	primary->max_downscale = 1;
> > +	if (INTEL_INFO(dev)->gen >= 9) {
> > +		primary->can_scale = true;
> > +	}
> >  	state->scaler_id = -1;
> >  	primary->pipe = pipe;
> >  	primary->plane = pipe;
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h
> > b/drivers/gpu/drm/i915/intel_drv.h
> > index 7b28bff..0543150 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -1125,6 +1125,7 @@ void skl_detach_scalers(struct intel_crtc
> > *intel_crtc);  int skl_update_scaler_users(struct intel_crtc *intel_crtc,
> >  	struct intel_crtc_state *crtc_state, struct intel_plane *intel_plane,
> >  	struct intel_plane_state *plane_state, int force_detach);
> > +int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state
> > +*crtc_state);
> >
> >  unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
> >  				     struct drm_i915_gem_object *obj); diff --git
> > a/drivers/gpu/drm/i915/intel_sprite.c
> > b/drivers/gpu/drm/i915/intel_sprite.c
> > index c05fb36..955965c 100644
> > --- a/drivers/gpu/drm/i915/intel_sprite.c
> > +++ b/drivers/gpu/drm/i915/intel_sprite.c
> > @@ -1119,6 +1119,15 @@ int intel_sprite_set_colorkey(struct drm_device
> *dev, void *data,
> >  	}
> >
> >  	intel_plane = to_intel_plane(plane);
> > +
> > +	if (INTEL_INFO(dev)->gen >= 9) {
> > +		/* plane scaling and colorkey are mutually exclusive */
> > +		if (to_intel_plane_state(plane->state)->scaler_id >= 0) {
> > +			DRM_ERROR("colorkey not allowed with scaler\n");
> > +			return -EINVAL;
> > +		}
> > +	}
> > +
> >  	intel_plane->ckey = *set;
> >
> >  	/*
> > --
> > 1.7.9.5
> >
> 
> --
> Matt Roper
> Graphics Software Engineer
> IoTG Platform Enabling & Development
> Intel Corporation
> (916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 00/14] skylake display scalers
  2015-04-09 22:12   ` Matt Roper
@ 2015-04-09 22:22     ` Konduru, Chandra
  0 siblings, 0 replies; 54+ messages in thread
From: Konduru, Chandra @ 2015-04-09 22:22 UTC (permalink / raw)
  To: Roper, Matthew D; +Cc: Vetter, Daniel, intel-gfx, Conselvan De Oliveira, Ander



> -----Original Message-----
> From: Roper, Matthew D
> Sent: Thursday, April 09, 2015 3:12 PM
> To: Konduru, Chandra
> Cc: intel-gfx@lists.freedesktop.org; Vetter, Daniel; Conselvan De Oliveira, Ander
> Subject: Re: [PATCH 00/14] skylake display scalers
> 
> On Thu, Apr 09, 2015 at 02:53:38PM -0700, Matt Roper wrote:
> > On Tue, Apr 07, 2015 at 03:28:33PM -0700, Chandra Konduru wrote:
> > > Primary changes in this version are:
> > > 1) Moved num_scalers to crtc
> > > 2) Changed src/dst rect ranges to #defines
> > > 3) Dropped scaling ratios from state instead calculating when needed
> > > 4) Dropped filter from scaler
> > > 5) Squashed helper functions from standalone patches into patch
> > > where 1st used
> > > 6) Kept sprite src tect in 16.16 format
> > >
> > > Though changes are minor but they got sprinkled into multiple patches.
> > >
> > > Sending full patch series for completeness. Individual patch headers
> > > have additional details on changes. This series should cleanly merge
> > > to latest drm-intel-nighly.
> >
> > Okay, this is looking pretty good now.  I only spotted a single issue
> > (which affects patches #6 and #13); all of the other patches are
> >
> > Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
> >
> > I also requested an update to the commit message of patch #9, but the
> > code itself looks fine and still has my r-b.
> 
> Oh, one thing I forgot to mention.  My understanding is that while we're on
> transitional plane helpers, your scaler setup code still isn't going to get run
> properly for legacy SetPlane ioctl calls (correct me if I'm wrong and overlooked
> a change related to that).  I know Maarten is working on addressing the issues
> with the full atomic helpers properly, but I also have a bit of a workaround patch
> that might be useful in the time being here:
> 
>         http://patchwork.freedesktop.org/patch/46773/
> 
> Do you think we need to make sure we're switched back to the full atomic
> helpers via one of those solutions before merging your series here?
This isn't really needed because I did run all my tests with both current transitional helpers 
and switch to full atomic helpers and made sure test run properly in both cases. 
Only diff is with transitional helpers scaling feature isn't available with full atomic 
helpers scaling is available. This series can be merged into current nightly.

> 
> 
> Matt
> 
> >
> >
> > Matt
> >
> > >
> > > Chandra Konduru (14):
> > >   drm: Adding drm helper function drm_plane_from_index().
> > >   drm/i915: Register definitions for skylake scalers
> > >   drm/i915: skylake scaler structure definitions
> > >   drm/i915: Initialize plane colorkey to NONE
> > >   drm/i915: Initialize skylake scalers
> > >   drm/i915: Keep sprite plane src rect in 16.16 format
> > >   drm/i915: Dump scaler_state too as part of dumping crtc_state
> > >   drm/i915: Preserve scaler state when clearing crtc_state
> > >   drm/i915: setup scalers for crtc_compute_config
> > >   drm/i915: Ensure setting up scalers into staged crtc_state
> > >   drm/i915: copy staged scaler state from drm state to crtc->config.
> > >   drm/i915: skylake panel fitting using shared scalers
> > >   drm/i915: skylake primary plane scaling using shared scalers
> > >   drm/i915: skylake sprite plane scaling using shared scalers
> > >
> > >  drivers/gpu/drm/drm_crtc.c           |   22 ++
> > >  drivers/gpu/drm/i915/i915_reg.h      |  115 +++++++++
> > >  drivers/gpu/drm/i915/intel_atomic.c  |  163 +++++++++++++
> > > drivers/gpu/drm/i915/intel_display.c |  441
> +++++++++++++++++++++++++++++++---
> > >  drivers/gpu/drm/i915/intel_dp.c      |    8 +
> > >  drivers/gpu/drm/i915/intel_drv.h     |   76 ++++++
> > >  drivers/gpu/drm/i915/intel_sprite.c  |   83 +++++--
> > >  include/drm/drm_crtc.h               |    1 +
> > >  8 files changed, 855 insertions(+), 54 deletions(-)
> > >
> > > --
> > > 1.7.9.5
> > >
> >
> > --
> > Matt Roper
> > Graphics Software Engineer
> > IoTG Platform Enabling & Development
> > Intel Corporation
> > (916) 356-2795
> 
> --
> Matt Roper
> Graphics Software Engineer
> IoTG Platform Enabling & Development
> Intel Corporation
> (916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 06/14] drm/i915: Keep sprite plane src rect in 16.16 format
  2015-04-09 22:08     ` Konduru, Chandra
@ 2015-04-09 22:22       ` Matt Roper
  2015-04-09 22:27         ` Konduru, Chandra
  0 siblings, 1 reply; 54+ messages in thread
From: Matt Roper @ 2015-04-09 22:22 UTC (permalink / raw)
  To: Konduru, Chandra; +Cc: Vetter, Daniel, intel-gfx, Conselvan De Oliveira, Ander

On Thu, Apr 09, 2015 at 03:08:55PM -0700, Konduru, Chandra wrote:
> 
> 
> > -----Original Message-----
> > From: Roper, Matthew D
> > Sent: Thursday, April 09, 2015 2:51 PM
> > To: Konduru, Chandra
> > Cc: intel-gfx@lists.freedesktop.org; Vetter, Daniel; Conselvan De Oliveira, Ander
> > Subject: Re: [PATCH 06/14] drm/i915: Keep sprite plane src rect in 16.16 format
> > 
> > On Tue, Apr 07, 2015 at 03:28:39PM -0700, Chandra Konduru wrote:
> > > This patch keeps intel_plane_state->src rect back into 16.16 format.
> > >
> > > v2:
> > > -sprite src rect to match primary format (Matt, Daniel)
> > >
> > > Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
> > 
> > This looks good, and matches what we had discussed, but don't you also need to
> > add the corresponding unshift in intel_commit_sprite_plane() when we actually
> > pull the values out and make use of them?  
> The unshift is in patch #14 which should have been in this patch.
> 
> From #14 relevant hunk is:
> @@ -1081,10 +1122,10 @@ intel_commit_sprite_plane(struct drm_plane *plane,
>             crtc_y = state->dst.y1;
>             crtc_w = drm_rect_width(&state->dst);
>             crtc_h = drm_rect_height(&state->dst);
> -           src_x = state->src.x1;
> -           src_y = state->src.y1;
> -           src_w = drm_rect_width(&state->src);
> -           src_h = drm_rect_height(&state->src);
> +           src_x = state->src.x1 >> 16;
> +           src_y = state->src.y1 >> 16;
> +           src_w = drm_rect_width(&state->src) >> 16;
> +           src_h = drm_rect_height(&state->src) >> 16;
>             intel_plane->update_plane(plane, crtc, fb,
>                           crtc_x, crtc_y, crtc_w, crtc_h,
>                           src_x, src_y, src_w, src_h);

Yep, you're right; I got the patch numbers mixed up while flipping back
and forth between patches, and then confused myself further by looking
at the wrong patch while writing my follow up reply.

As long as we pull this hunk from #14 back into this patch, that should
be the proper fix.  You can ignore my other comments below where I was
just confusing myself by looking at the wrong patch numbers.


Matt

> 
> > The goal is to keep the meaning of
> > the structure fields consistent at all times
> > (16.16 fixed pt), but once we pull the values out of the structure, we wind up
> > passing them to functions that doing use fixed point, so we do need to unshift at
> > that point.
> > 
> > It looks like in patch #13 you do switch the low-level
> > skl_update_plane() to make use of 16.16 input parameters.  However any
> > commit that we bisect through between #6 and #13 is going to wind up treating
> > 16.16 values as integer values, which I assume will blow up.
> Patch #13 doesn't touches skl_update_plane(). Perhaps you may be referring to #14.
> In #14, it does unshift as I mentioned above. I think I need to move above hunk
> to #6 to fix any potential issue due to bisect.
> 
> Let me know if you see any potential issue after moving the above hunk to #6.
> 
> > Also, you haven't touched any of the other platforms (ilk, vlv, ivb,
> > etc.) so they're all still going to have problems.
> Shifting and unshifting is happening in intel_check_plane and intel_commit_plane
> which is common for all platforms. I don't see what the problem you
> are referring to?
> > 
> > I think the easiest short-term solution is to do the unshifting in commit_plane
> > and leave the hardware-specific programming functions as-is.  
> This is what I'm doing now keeping platform_update_plane(parameters) use
> unshifted values (i.e., regular ints). I don't see any value to pass function parameters
> as 16.16 values. If there is a need arise we can change the semantics of parameters
> at a later time. 
> 
> > Longer term,
> > maybe it makes sense for a future patchset to change the actual register-
> > programming functions (foo_update_plane) so that they take a plane_state
> > directly and do their own unshifting?  In that case we'd need to update them to
> > do their own unshifting, but at least we wouldn't have to pull all the values out in
> > commit_plane, just to pass them to these functions.
> > 
> > 
> > Matt
> > 
> > > ---
> > >  drivers/gpu/drm/i915/intel_sprite.c |    8 ++++----
> > >  1 file changed, 4 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/i915/intel_sprite.c
> > > b/drivers/gpu/drm/i915/intel_sprite.c
> > > index ac4aa68..c05fb36 100644
> > > --- a/drivers/gpu/drm/i915/intel_sprite.c
> > > +++ b/drivers/gpu/drm/i915/intel_sprite.c
> > > @@ -1006,10 +1006,10 @@ intel_check_sprite_plane(struct drm_plane
> > *plane,
> > >  	}
> > >
> > >  	if (state->visible) {
> > > -		src->x1 = src_x;
> > > -		src->x2 = src_x + src_w;
> > > -		src->y1 = src_y;
> > > -		src->y2 = src_y + src_h;
> > > +		src->x1 = src_x << 16;
> > > +		src->x2 = (src_x + src_w) << 16;
> > > +		src->y1 = src_y << 16;
> > > +		src->y2 = (src_y + src_h) << 16;
> > >  	}
> > >
> > >  	dst->x1 = crtc_x;
> > > --
> > > 1.7.9.5
> > >
> > 
> > --
> > Matt Roper
> > Graphics Software Engineer
> > IoTG Platform Enabling & Development
> > Intel Corporation
> > (916) 356-2795

-- 
Matt Roper
Graphics Software Engineer
IoTG Platform Enabling & Development
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 06/14] drm/i915: Keep sprite plane src rect in 16.16 format
  2015-04-09 22:22       ` Matt Roper
@ 2015-04-09 22:27         ` Konduru, Chandra
  0 siblings, 0 replies; 54+ messages in thread
From: Konduru, Chandra @ 2015-04-09 22:27 UTC (permalink / raw)
  To: Roper, Matthew D; +Cc: Vetter, Daniel, intel-gfx, Conselvan De Oliveira, Ander



> -----Original Message-----
> From: Roper, Matthew D
> Sent: Thursday, April 09, 2015 3:23 PM
> To: Konduru, Chandra
> Cc: intel-gfx@lists.freedesktop.org; Vetter, Daniel; Conselvan De Oliveira, Ander
> Subject: Re: [PATCH 06/14] drm/i915: Keep sprite plane src rect in 16.16 format
> 
> On Thu, Apr 09, 2015 at 03:08:55PM -0700, Konduru, Chandra wrote:
> >
> >
> > > -----Original Message-----
> > > From: Roper, Matthew D
> > > Sent: Thursday, April 09, 2015 2:51 PM
> > > To: Konduru, Chandra
> > > Cc: intel-gfx@lists.freedesktop.org; Vetter, Daniel; Conselvan De
> > > Oliveira, Ander
> > > Subject: Re: [PATCH 06/14] drm/i915: Keep sprite plane src rect in
> > > 16.16 format
> > >
> > > On Tue, Apr 07, 2015 at 03:28:39PM -0700, Chandra Konduru wrote:
> > > > This patch keeps intel_plane_state->src rect back into 16.16 format.
> > > >
> > > > v2:
> > > > -sprite src rect to match primary format (Matt, Daniel)
> > > >
> > > > Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
> > >
> > > This looks good, and matches what we had discussed, but don't you
> > > also need to add the corresponding unshift in
> > > intel_commit_sprite_plane() when we actually pull the values out and make
> use of them?
> > The unshift is in patch #14 which should have been in this patch.
> >
> > From #14 relevant hunk is:
> > @@ -1081,10 +1122,10 @@ intel_commit_sprite_plane(struct drm_plane
> *plane,
> >             crtc_y = state->dst.y1;
> >             crtc_w = drm_rect_width(&state->dst);
> >             crtc_h = drm_rect_height(&state->dst);
> > -           src_x = state->src.x1;
> > -           src_y = state->src.y1;
> > -           src_w = drm_rect_width(&state->src);
> > -           src_h = drm_rect_height(&state->src);
> > +           src_x = state->src.x1 >> 16;
> > +           src_y = state->src.y1 >> 16;
> > +           src_w = drm_rect_width(&state->src) >> 16;
> > +           src_h = drm_rect_height(&state->src) >> 16;
> >             intel_plane->update_plane(plane, crtc, fb,
> >                           crtc_x, crtc_y, crtc_w, crtc_h,
> >                           src_x, src_y, src_w, src_h);
> 
> Yep, you're right; I got the patch numbers mixed up while flipping back and forth
> between patches, and then confused myself further by looking at the wrong
> patch while writing my follow up reply.
> 
> As long as we pull this hunk from #14 back into this patch, that should be the
> proper fix.  You can ignore my other comments below where I was just
> confusing myself by looking at the wrong patch numbers.

OK, then I will send #6, #14 updated (i.e., moving hunk from #14 to #6) and
#9 with updated commit message to address scaler quality.
 
> 
> 
> Matt
> 
> >
> > > The goal is to keep the meaning of
> > > the structure fields consistent at all times
> > > (16.16 fixed pt), but once we pull the values out of the structure,
> > > we wind up passing them to functions that doing use fixed point, so
> > > we do need to unshift at that point.
> > >
> > > It looks like in patch #13 you do switch the low-level
> > > skl_update_plane() to make use of 16.16 input parameters.  However
> > > any commit that we bisect through between #6 and #13 is going to
> > > wind up treating
> > > 16.16 values as integer values, which I assume will blow up.
> > Patch #13 doesn't touches skl_update_plane(). Perhaps you may be referring
> to #14.
> > In #14, it does unshift as I mentioned above. I think I need to move
> > above hunk to #6 to fix any potential issue due to bisect.
> >
> > Let me know if you see any potential issue after moving the above hunk to #6.
> >
> > > Also, you haven't touched any of the other platforms (ilk, vlv, ivb,
> > > etc.) so they're all still going to have problems.
> > Shifting and unshifting is happening in intel_check_plane and
> > intel_commit_plane which is common for all platforms. I don't see what
> > the problem you are referring to?
> > >
> > > I think the easiest short-term solution is to do the unshifting in
> > > commit_plane and leave the hardware-specific programming functions as-is.
> > This is what I'm doing now keeping platform_update_plane(parameters)
> > use unshifted values (i.e., regular ints). I don't see any value to
> > pass function parameters as 16.16 values. If there is a need arise we
> > can change the semantics of parameters at a later time.
> >
> > > Longer term,
> > > maybe it makes sense for a future patchset to change the actual
> > > register- programming functions (foo_update_plane) so that they take
> > > a plane_state directly and do their own unshifting?  In that case
> > > we'd need to update them to do their own unshifting, but at least we
> > > wouldn't have to pull all the values out in commit_plane, just to pass them to
> these functions.
> > >
> > >
> > > Matt
> > >
> > > > ---
> > > >  drivers/gpu/drm/i915/intel_sprite.c |    8 ++++----
> > > >  1 file changed, 4 insertions(+), 4 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/i915/intel_sprite.c
> > > > b/drivers/gpu/drm/i915/intel_sprite.c
> > > > index ac4aa68..c05fb36 100644
> > > > --- a/drivers/gpu/drm/i915/intel_sprite.c
> > > > +++ b/drivers/gpu/drm/i915/intel_sprite.c
> > > > @@ -1006,10 +1006,10 @@ intel_check_sprite_plane(struct drm_plane
> > > *plane,
> > > >  	}
> > > >
> > > >  	if (state->visible) {
> > > > -		src->x1 = src_x;
> > > > -		src->x2 = src_x + src_w;
> > > > -		src->y1 = src_y;
> > > > -		src->y2 = src_y + src_h;
> > > > +		src->x1 = src_x << 16;
> > > > +		src->x2 = (src_x + src_w) << 16;
> > > > +		src->y1 = src_y << 16;
> > > > +		src->y2 = (src_y + src_h) << 16;
> > > >  	}
> > > >
> > > >  	dst->x1 = crtc_x;
> > > > --
> > > > 1.7.9.5
> > > >
> > >
> > > --
> > > Matt Roper
> > > Graphics Software Engineer
> > > IoTG Platform Enabling & Development Intel Corporation
> > > (916) 356-2795
> 
> --
> Matt Roper
> Graphics Software Engineer
> IoTG Platform Enabling & Development
> Intel Corporation
> (916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 06/14] drm/i915: Keep sprite plane src rect in 16.16 format
  2015-04-07 22:28 ` [PATCH 06/14] drm/i915: Keep sprite plane src rect in 16.16 format Chandra Konduru
  2015-04-09 21:50   ` Matt Roper
@ 2015-04-09 23:41   ` Chandra Konduru
  2015-04-09 23:57     ` Matt Roper
  1 sibling, 1 reply; 54+ messages in thread
From: Chandra Konduru @ 2015-04-09 23:41 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira, daniel.vetter

This patch keeps intel_plane_state->src rect back
into 16.16 format.

v2:
-sprite src rect to match primary format (Matt, Daniel)

v3:
-moved a hunk from #14 to keep src rect in check & commit in tandom (Matt)

Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
---
 drivers/gpu/drm/i915/intel_sprite.c |   16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index ac4aa68..1ffbe86 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -1006,10 +1006,10 @@ intel_check_sprite_plane(struct drm_plane *plane,
 	}
 
 	if (state->visible) {
-		src->x1 = src_x;
-		src->x2 = src_x + src_w;
-		src->y1 = src_y;
-		src->y2 = src_y + src_h;
+		src->x1 = src_x << 16;
+		src->x2 = (src_x + src_w) << 16;
+		src->y1 = src_y << 16;
+		src->y2 = (src_y + src_h) << 16;
 	}
 
 	dst->x1 = crtc_x;
@@ -1081,10 +1081,10 @@ intel_commit_sprite_plane(struct drm_plane *plane,
 			crtc_y = state->dst.y1;
 			crtc_w = drm_rect_width(&state->dst);
 			crtc_h = drm_rect_height(&state->dst);
-			src_x = state->src.x1;
-			src_y = state->src.y1;
-			src_w = drm_rect_width(&state->src);
-			src_h = drm_rect_height(&state->src);
+			src_x = state->src.x1 >> 16;
+			src_y = state->src.y1 >> 16;
+			src_w = drm_rect_width(&state->src) >> 16;
+			src_h = drm_rect_height(&state->src) >> 16;
 			intel_plane->update_plane(plane, crtc, fb,
 						  crtc_x, crtc_y, crtc_w, crtc_h,
 						  src_x, src_y, src_w, src_h);
-- 
1.7.9.5

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

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

* [PATCH 09/14] drm/i915: setup scalers for crtc_compute_config
  2015-04-07 22:28 ` [PATCH 09/14] drm/i915: setup scalers for crtc_compute_config Chandra Konduru
  2015-04-09 21:51   ` Matt Roper
@ 2015-04-09 23:42   ` Chandra Konduru
  1 sibling, 0 replies; 54+ messages in thread
From: Chandra Konduru @ 2015-04-09 23:42 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira, daniel.vetter

Added intel_atomic_setup_scalers to setup scalers based on
staged scaling requests from a crtc and its planes. If staged
requests are supportable, this function assigns scalers to
requested planes and crtc. Note that the scaler assignement
itself is staged into crtc_state and respective plane_states
for later commit after all checks have been done.

overall high level flow:
 - scaler requests are staged into crtc_state by planes/crtc
 - check whether staged scaling requests can be supported
 - add planes using scalers that aren't in current transaction
 - assign scalers to requested users
 - as part of plane commit, scalers will be committed
   (i.e., either attached or detached) to respective planes in hw
 - as part of crtc_commit, scaler will be either attached or detached
   to crtc in hw

crtc_compute_config calls intel_atomic_setup_scalers() to start
scaler assignments as per scaler state in crtc config. This call
should be moved to atomic crtc once it is available.

v2:
-removed a log message (me)
-changed input parameter to crtc_state (me)

v3:
-remove assigning plane_state returned by drm_atomic_get_plane_state (Matt)
-fail if there is an error from drm_atomic_get_plane_state (Matt)

v4:
-changes to align with updated scaler structure (Matt, me)

v5:
-added addtional checks before enabling HQ mode (me)
-added comments to enable HQ mode (Matt)

Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
---
 drivers/gpu/drm/i915/intel_atomic.c  |  148 ++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_display.c |   10 ++-
 drivers/gpu/drm/i915/intel_drv.h     |    3 +
 3 files changed, 160 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 3903b90..e394f61 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -241,3 +241,151 @@ intel_crtc_destroy_state(struct drm_crtc *crtc,
 {
 	drm_atomic_helper_crtc_destroy_state(crtc, state);
 }
+
+/**
+ * intel_atomic_setup_scalers() - setup scalers for crtc per staged requests
+ * @dev: DRM device
+ * @crtc: intel crtc
+ * @crtc_state: incoming crtc_state to validate and setup scalers
+ *
+ * This function sets up scalers based on staged scaling requests for
+ * a @crtc and its planes. It is called from crtc level check path. If request
+ * is a supportable request, it attaches scalers to requested planes and crtc.
+ *
+ * This function takes into account the current scaler(s) in use by any planes
+ * not being part of this atomic state
+ *
+ *  Returns:
+ *         0 - scalers were setup succesfully
+ *         error code - otherwise
+ */
+int intel_atomic_setup_scalers(struct drm_device *dev,
+	struct intel_crtc *intel_crtc,
+	struct intel_crtc_state *crtc_state)
+{
+	struct drm_plane *plane = NULL;
+	struct intel_plane *intel_plane;
+	struct intel_plane_state *plane_state = NULL;
+	struct intel_crtc_scaler_state *scaler_state;
+	struct drm_atomic_state *drm_state;
+	int num_scalers_need;
+	int i, j;
+
+	if (INTEL_INFO(dev)->gen < 9 || !intel_crtc || !crtc_state)
+		return 0;
+
+	scaler_state = &crtc_state->scaler_state;
+	drm_state = crtc_state->base.state;
+
+	num_scalers_need = hweight32(scaler_state->scaler_users);
+	DRM_DEBUG_KMS("crtc_state = %p need = %d avail = %d scaler_users = 0x%x\n",
+		crtc_state, num_scalers_need, intel_crtc->num_scalers,
+		scaler_state->scaler_users);
+
+	/*
+	 * High level flow:
+	 * - staged scaler requests are already in scaler_state->scaler_users
+	 * - check whether staged scaling requests can be supported
+	 * - add planes using scalers that aren't in current transaction
+	 * - assign scalers to requested users
+	 * - as part of plane commit, scalers will be committed
+	 *   (i.e., either attached or detached) to respective planes in hw
+	 * - as part of crtc_commit, scaler will be either attached or detached
+	 *   to crtc in hw
+	 */
+
+	/* fail if required scalers > available scalers */
+	if (num_scalers_need > intel_crtc->num_scalers){
+		DRM_DEBUG_KMS("Too many scaling requests %d > %d\n",
+			num_scalers_need, intel_crtc->num_scalers);
+		return -EINVAL;
+	}
+
+	/* walkthrough scaler_users bits and start assigning scalers */
+	for (i = 0; i < sizeof(scaler_state->scaler_users) * 8; i++) {
+		int *scaler_id;
+
+		/* skip if scaler not required */
+		if (!(scaler_state->scaler_users & (1 << i)))
+			continue;
+
+		if (i == SKL_CRTC_INDEX) {
+			/* panel fitter case: assign as a crtc scaler */
+			scaler_id = &scaler_state->scaler_id;
+		} else {
+			if (!drm_state)
+				continue;
+
+			/* plane scaler case: assign as a plane scaler */
+			/* find the plane that set the bit as scaler_user */
+			plane = drm_state->planes[i];
+
+			/*
+			 * to enable/disable hq mode, add planes that are using scaler
+			 * into this transaction
+			 */
+			if (!plane) {
+				struct drm_plane_state *state;
+				plane = drm_plane_from_index(dev, i);
+				state = drm_atomic_get_plane_state(drm_state, plane);
+				if (IS_ERR(state)) {
+					DRM_DEBUG_KMS("Failed to add [PLANE:%d] to drm_state\n",
+						plane->base.id);
+					return PTR_ERR(state);
+				}
+			}
+
+			intel_plane = to_intel_plane(plane);
+
+			/* plane on different crtc cannot be a scaler user of this crtc */
+			if (WARN_ON(intel_plane->pipe != intel_crtc->pipe)) {
+				continue;
+			}
+
+			plane_state = to_intel_plane_state(drm_state->plane_states[i]);
+			scaler_id = &plane_state->scaler_id;
+		}
+
+		if (*scaler_id < 0) {
+			/* find a free scaler */
+			for (j = 0; j < intel_crtc->num_scalers; j++) {
+				if (!scaler_state->scalers[j].in_use) {
+					scaler_state->scalers[j].in_use = 1;
+					*scaler_id = scaler_state->scalers[j].id;
+					DRM_DEBUG_KMS("Attached scaler id %u.%u to %s:%d\n",
+						intel_crtc->pipe,
+						i == SKL_CRTC_INDEX ? scaler_state->scaler_id :
+							plane_state->scaler_id,
+						i == SKL_CRTC_INDEX ? "CRTC" : "PLANE",
+						i == SKL_CRTC_INDEX ?  intel_crtc->base.base.id :
+						plane->base.id);
+					break;
+				}
+			}
+		}
+
+		if (WARN_ON(*scaler_id < 0)) {
+			DRM_DEBUG_KMS("Cannot find scaler for %s:%d\n",
+				i == SKL_CRTC_INDEX ? "CRTC" : "PLANE",
+				i == SKL_CRTC_INDEX ? intel_crtc->base.base.id:plane->base.id);
+			continue;
+		}
+
+		/* set scaler mode */
+		if (num_scalers_need == 1 && intel_crtc->pipe != PIPE_C) {
+			/*
+			 * when only 1 scaler is in use on either pipe A or B,
+			 * scaler 0 operates in high quality (HQ) mode.
+			 * In this case use scaler 0 to take advantage of HQ mode
+			 */
+			*scaler_id = 0;
+			scaler_state->scalers[0].in_use = 1;
+			scaler_state->scalers[0].mode = PS_SCALER_MODE_HQ;
+			scaler_state->scalers[1].in_use = 0;
+		} else {
+			scaler_state->scalers[*scaler_id].mode = PS_SCALER_MODE_DYN;
+		}
+	}
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f1051f0..9691768 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5809,6 +5809,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	int ret;
 
 	/* FIXME should check pixel clock limits on all platforms */
 	if (INTEL_INFO(dev)->gen < 4) {
@@ -5863,7 +5864,14 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
 	if (pipe_config->has_pch_encoder)
 		return ironlake_fdi_compute_config(crtc, pipe_config);
 
-	return 0;
+	/* FIXME: remove below call once atomic mode set is place and all crtc
+	 * related checks called from atomic_crtc_check function */
+	ret = 0;
+	DRM_DEBUG_KMS("intel_crtc = %p drm_state (pipe_config->base.state) = %p\n",
+		crtc, pipe_config->base.state);
+	ret = intel_atomic_setup_scalers(dev, crtc, pipe_config);
+
+	return ret;
 }
 
 static int skylake_get_display_clock_speed(struct drm_device *dev)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index adca692..f9614fb 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1382,6 +1382,9 @@ intel_atomic_get_crtc_state(struct drm_atomic_state *state,
 
 	return to_intel_crtc_state(crtc_state);
 }
+int intel_atomic_setup_scalers(struct drm_device *dev,
+	struct intel_crtc *intel_crtc,
+	struct intel_crtc_state *crtc_state);
 
 /* intel_atomic_plane.c */
 struct intel_plane_state *intel_create_plane_state(struct drm_plane *plane);
-- 
1.7.9.5

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

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

* [PATCH 14/14] drm/i915: skylake sprite plane scaling using shared scalers
  2015-04-07 22:28 ` [PATCH 14/14] drm/i915: skylake sprite " Chandra Konduru
@ 2015-04-09 23:43   ` Chandra Konduru
  2015-04-10  0:01     ` Matt Roper
  2015-04-15 22:15   ` Chandra Konduru
  1 sibling, 1 reply; 54+ messages in thread
From: Chandra Konduru @ 2015-04-09 23:43 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira, daniel.vetter

This patch enables skylake sprite plane display scaling using shared
scalers atomic desgin.

v2:
-use single copy of scaler limits (Matt)

v3:
-detaching scalers moved to crtc commit path (Matt)

v4:
-changes to align with updated scaler structures (Matt, me)
-keep sprite src rect in 16.16 format (Matt, Daniel)

v5:
-moved a hunk to #6 to keep src rect in check & commit in tandom (Matt)

Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
---
 drivers/gpu/drm/i915/intel_sprite.c |   56 ++++++++++++++++++++++++++++-------
 1 file changed, 46 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index c346a82..ae503ee 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -33,6 +33,7 @@
 #include <drm/drm_crtc.h>
 #include <drm/drm_fourcc.h>
 #include <drm/drm_rect.h>
+#include <drm/drm_atomic.h>
 #include <drm/drm_plane_helper.h>
 #include "intel_drv.h"
 #include <drm/i915_drm.h>
@@ -194,6 +195,8 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
 	int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
 	const struct drm_intel_sprite_colorkey *key = &intel_plane->ckey;
 	unsigned long surf_addr;
+	struct intel_crtc_state *crtc_state = to_intel_crtc(crtc)->config;
+	int scaler_id;
 
 	plane_ctl = PLANE_CTL_ENABLE |
 		PLANE_CTL_PIPE_CSC_ENABLE;
@@ -264,6 +267,8 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
 	stride_div = intel_fb_stride_alignment(dev, fb->modifier[0],
 					       fb->pixel_format);
 
+	scaler_id = to_intel_plane_state(drm_plane->state)->scaler_id;
+
 	/* Sizes are 0 based */
 	src_w--;
 	src_h--;
@@ -283,10 +288,29 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
 
 	surf_addr = intel_plane_obj_offset(intel_plane, obj);
 
+	/* program plane scaler */
+	if (scaler_id >= 0) {
+		uint32_t ps_ctrl = 0;
+
+		DRM_DEBUG_KMS("plane = %d PS_PLANE_SEL(plane) = 0x%x\n", plane,
+			PS_PLANE_SEL(plane));
+		ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(plane) |
+			crtc_state->scaler_state.scalers[scaler_id].mode;
+		I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
+		I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
+		I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
+		I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id),
+			((crtc_w + 1) << 16)|(crtc_h + 1));
+
+		I915_WRITE(PLANE_POS(pipe, plane), 0);
+		I915_WRITE(PLANE_SIZE(pipe, plane), (src_h << 16) | src_w);
+	} else {
+		I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x);
+		I915_WRITE(PLANE_SIZE(pipe, plane), (crtc_h << 16) | crtc_w);
+	}
+
 	I915_WRITE(PLANE_OFFSET(pipe, plane), (y << 16) | x);
 	I915_WRITE(PLANE_STRIDE(pipe, plane), fb->pitches[0] / stride_div);
-	I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x);
-	I915_WRITE(PLANE_SIZE(pipe, plane), (crtc_h << 16) | crtc_w);
 	I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl);
 	I915_WRITE(PLANE_SURF(pipe, plane), surf_addr);
 	POSTING_READ(PLANE_SURF(pipe, plane));
@@ -863,7 +887,9 @@ static int
 intel_check_sprite_plane(struct drm_plane *plane,
 			 struct intel_plane_state *state)
 {
+	struct drm_device *dev = plane->dev;
 	struct intel_crtc *intel_crtc = to_intel_crtc(state->base.crtc);
+	struct intel_crtc_state *crtc_state;
 	struct intel_plane *intel_plane = to_intel_plane(plane);
 	struct drm_framebuffer *fb = state->base.fb;
 	int crtc_x, crtc_y;
@@ -875,8 +901,11 @@ intel_check_sprite_plane(struct drm_plane *plane,
 	int hscale, vscale;
 	int max_scale, min_scale;
 	int pixel_size;
+	int ret;
 
 	intel_crtc = intel_crtc ? intel_crtc : to_intel_crtc(plane->crtc);
+	crtc_state = state->base.state ?
+		intel_atomic_get_crtc_state(state->base.state, intel_crtc) : NULL;
 
 	if (!fb) {
 		state->visible = false;
@@ -903,6 +932,11 @@ intel_check_sprite_plane(struct drm_plane *plane,
 	max_scale = intel_plane->max_downscale << 16;
 	min_scale = intel_plane->can_scale ? 1 : (1 << 16);
 
+	if (INTEL_INFO(dev)->gen >= 9) {
+		min_scale = 1;
+		max_scale = skl_max_scale(intel_crtc, crtc_state);
+	}
+
 	drm_rect_rotate(src, fb->width << 16, fb->height << 16,
 			state->base.rotation);
 
@@ -998,8 +1032,8 @@ intel_check_sprite_plane(struct drm_plane *plane,
 		width_bytes = ((src_x * pixel_size) & 63) +
 					src_w * pixel_size;
 
-		if (src_w > 2048 || src_h > 2048 ||
-		    width_bytes > 4096 || fb->pitches[0] > 4096) {
+		if (INTEL_INFO(dev)->gen < 9 && (src_w > 2048 || src_h > 2048 ||
+		    width_bytes > 4096 || fb->pitches[0] > 4096)) {
 			DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
 			return -EINVAL;
 		}
@@ -1053,6 +1087,13 @@ finish:
 		}
 	}
 
+	if (INTEL_INFO(dev)->gen >= 9) {
+		ret = skl_update_scaler_users(intel_crtc, crtc_state, intel_plane,
+			state, 0);
+		if (ret)
+			return ret;
+	}
+
 	return 0;
 }
 
@@ -1264,12 +1305,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
 		}
 		break;
 	case 9:
-		/*
-		 * FIXME: Skylake planes can be scaled (with some restrictions),
-		 * but this is for another time.
-		 */
-		intel_plane->can_scale = false;
-		intel_plane->max_downscale = 1;
+		intel_plane->can_scale = true;
 		intel_plane->update_plane = skl_update_plane;
 		intel_plane->disable_plane = skl_disable_plane;
 		state->scaler_id = -1;
-- 
1.7.9.5

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

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

* Re: [PATCH 06/14] drm/i915: Keep sprite plane src rect in 16.16 format
  2015-04-09 23:41   ` Chandra Konduru
@ 2015-04-09 23:57     ` Matt Roper
  0 siblings, 0 replies; 54+ messages in thread
From: Matt Roper @ 2015-04-09 23:57 UTC (permalink / raw)
  To: Chandra Konduru; +Cc: daniel.vetter, intel-gfx, ander.conselvan.de.oliveira

On Thu, Apr 09, 2015 at 04:41:54PM -0700, Chandra Konduru wrote:
> This patch keeps intel_plane_state->src rect back
> into 16.16 format.
> 
> v2:
> -sprite src rect to match primary format (Matt, Daniel)
> 
> v3:
> -moved a hunk from #14 to keep src rect in check & commit in tandom (Matt)
> 
> Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>

Reviewed-by: Matt Roper <matthew.d.roper@intel.com>

> ---
>  drivers/gpu/drm/i915/intel_sprite.c |   16 ++++++++--------
>  1 file changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index ac4aa68..1ffbe86 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -1006,10 +1006,10 @@ intel_check_sprite_plane(struct drm_plane *plane,
>  	}
>  
>  	if (state->visible) {
> -		src->x1 = src_x;
> -		src->x2 = src_x + src_w;
> -		src->y1 = src_y;
> -		src->y2 = src_y + src_h;
> +		src->x1 = src_x << 16;
> +		src->x2 = (src_x + src_w) << 16;
> +		src->y1 = src_y << 16;
> +		src->y2 = (src_y + src_h) << 16;
>  	}
>  
>  	dst->x1 = crtc_x;
> @@ -1081,10 +1081,10 @@ intel_commit_sprite_plane(struct drm_plane *plane,
>  			crtc_y = state->dst.y1;
>  			crtc_w = drm_rect_width(&state->dst);
>  			crtc_h = drm_rect_height(&state->dst);
> -			src_x = state->src.x1;
> -			src_y = state->src.y1;
> -			src_w = drm_rect_width(&state->src);
> -			src_h = drm_rect_height(&state->src);
> +			src_x = state->src.x1 >> 16;
> +			src_y = state->src.y1 >> 16;
> +			src_w = drm_rect_width(&state->src) >> 16;
> +			src_h = drm_rect_height(&state->src) >> 16;
>  			intel_plane->update_plane(plane, crtc, fb,
>  						  crtc_x, crtc_y, crtc_w, crtc_h,
>  						  src_x, src_y, src_w, src_h);
> -- 
> 1.7.9.5
> 

-- 
Matt Roper
Graphics Software Engineer
IoTG Platform Enabling & Development
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 14/14] drm/i915: skylake sprite plane scaling using shared scalers
  2015-04-09 23:43   ` Chandra Konduru
@ 2015-04-10  0:01     ` Matt Roper
  0 siblings, 0 replies; 54+ messages in thread
From: Matt Roper @ 2015-04-10  0:01 UTC (permalink / raw)
  To: Chandra Konduru; +Cc: daniel.vetter, intel-gfx, ander.conselvan.de.oliveira

On Thu, Apr 09, 2015 at 04:43:32PM -0700, Chandra Konduru wrote:
> This patch enables skylake sprite plane display scaling using shared
> scalers atomic desgin.
> 
> v2:
> -use single copy of scaler limits (Matt)
> 
> v3:
> -detaching scalers moved to crtc commit path (Matt)
> 
> v4:
> -changes to align with updated scaler structures (Matt, me)
> -keep sprite src rect in 16.16 format (Matt, Daniel)
> 
> v5:
> -moved a hunk to #6 to keep src rect in check & commit in tandom (Matt)
> 
> Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>

Reviewed-by: Matt Roper <matthew.d.roper@intel.com>

> ---
>  drivers/gpu/drm/i915/intel_sprite.c |   56 ++++++++++++++++++++++++++++-------
>  1 file changed, 46 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index c346a82..ae503ee 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -33,6 +33,7 @@
>  #include <drm/drm_crtc.h>
>  #include <drm/drm_fourcc.h>
>  #include <drm/drm_rect.h>
> +#include <drm/drm_atomic.h>
>  #include <drm/drm_plane_helper.h>
>  #include "intel_drv.h"
>  #include <drm/i915_drm.h>
> @@ -194,6 +195,8 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
>  	int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
>  	const struct drm_intel_sprite_colorkey *key = &intel_plane->ckey;
>  	unsigned long surf_addr;
> +	struct intel_crtc_state *crtc_state = to_intel_crtc(crtc)->config;
> +	int scaler_id;
>  
>  	plane_ctl = PLANE_CTL_ENABLE |
>  		PLANE_CTL_PIPE_CSC_ENABLE;
> @@ -264,6 +267,8 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
>  	stride_div = intel_fb_stride_alignment(dev, fb->modifier[0],
>  					       fb->pixel_format);
>  
> +	scaler_id = to_intel_plane_state(drm_plane->state)->scaler_id;
> +
>  	/* Sizes are 0 based */
>  	src_w--;
>  	src_h--;
> @@ -283,10 +288,29 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
>  
>  	surf_addr = intel_plane_obj_offset(intel_plane, obj);
>  
> +	/* program plane scaler */
> +	if (scaler_id >= 0) {
> +		uint32_t ps_ctrl = 0;
> +
> +		DRM_DEBUG_KMS("plane = %d PS_PLANE_SEL(plane) = 0x%x\n", plane,
> +			PS_PLANE_SEL(plane));
> +		ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(plane) |
> +			crtc_state->scaler_state.scalers[scaler_id].mode;
> +		I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
> +		I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
> +		I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
> +		I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id),
> +			((crtc_w + 1) << 16)|(crtc_h + 1));
> +
> +		I915_WRITE(PLANE_POS(pipe, plane), 0);
> +		I915_WRITE(PLANE_SIZE(pipe, plane), (src_h << 16) | src_w);
> +	} else {
> +		I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x);
> +		I915_WRITE(PLANE_SIZE(pipe, plane), (crtc_h << 16) | crtc_w);
> +	}
> +
>  	I915_WRITE(PLANE_OFFSET(pipe, plane), (y << 16) | x);
>  	I915_WRITE(PLANE_STRIDE(pipe, plane), fb->pitches[0] / stride_div);
> -	I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x);
> -	I915_WRITE(PLANE_SIZE(pipe, plane), (crtc_h << 16) | crtc_w);
>  	I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl);
>  	I915_WRITE(PLANE_SURF(pipe, plane), surf_addr);
>  	POSTING_READ(PLANE_SURF(pipe, plane));
> @@ -863,7 +887,9 @@ static int
>  intel_check_sprite_plane(struct drm_plane *plane,
>  			 struct intel_plane_state *state)
>  {
> +	struct drm_device *dev = plane->dev;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(state->base.crtc);
> +	struct intel_crtc_state *crtc_state;
>  	struct intel_plane *intel_plane = to_intel_plane(plane);
>  	struct drm_framebuffer *fb = state->base.fb;
>  	int crtc_x, crtc_y;
> @@ -875,8 +901,11 @@ intel_check_sprite_plane(struct drm_plane *plane,
>  	int hscale, vscale;
>  	int max_scale, min_scale;
>  	int pixel_size;
> +	int ret;
>  
>  	intel_crtc = intel_crtc ? intel_crtc : to_intel_crtc(plane->crtc);
> +	crtc_state = state->base.state ?
> +		intel_atomic_get_crtc_state(state->base.state, intel_crtc) : NULL;
>  
>  	if (!fb) {
>  		state->visible = false;
> @@ -903,6 +932,11 @@ intel_check_sprite_plane(struct drm_plane *plane,
>  	max_scale = intel_plane->max_downscale << 16;
>  	min_scale = intel_plane->can_scale ? 1 : (1 << 16);
>  
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		min_scale = 1;
> +		max_scale = skl_max_scale(intel_crtc, crtc_state);
> +	}
> +
>  	drm_rect_rotate(src, fb->width << 16, fb->height << 16,
>  			state->base.rotation);
>  
> @@ -998,8 +1032,8 @@ intel_check_sprite_plane(struct drm_plane *plane,
>  		width_bytes = ((src_x * pixel_size) & 63) +
>  					src_w * pixel_size;
>  
> -		if (src_w > 2048 || src_h > 2048 ||
> -		    width_bytes > 4096 || fb->pitches[0] > 4096) {
> +		if (INTEL_INFO(dev)->gen < 9 && (src_w > 2048 || src_h > 2048 ||
> +		    width_bytes > 4096 || fb->pitches[0] > 4096)) {
>  			DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
>  			return -EINVAL;
>  		}
> @@ -1053,6 +1087,13 @@ finish:
>  		}
>  	}
>  
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		ret = skl_update_scaler_users(intel_crtc, crtc_state, intel_plane,
> +			state, 0);
> +		if (ret)
> +			return ret;
> +	}
> +
>  	return 0;
>  }
>  
> @@ -1264,12 +1305,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
>  		}
>  		break;
>  	case 9:
> -		/*
> -		 * FIXME: Skylake planes can be scaled (with some restrictions),
> -		 * but this is for another time.
> -		 */
> -		intel_plane->can_scale = false;
> -		intel_plane->max_downscale = 1;
> +		intel_plane->can_scale = true;
>  		intel_plane->update_plane = skl_update_plane;
>  		intel_plane->disable_plane = skl_disable_plane;
>  		state->scaler_id = -1;
> -- 
> 1.7.9.5
> 

-- 
Matt Roper
Graphics Software Engineer
IoTG Platform Enabling & Development
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 01/14] drm: Adding drm helper function drm_plane_from_index().
  2015-04-07 22:28 ` [PATCH 01/14] drm: Adding drm helper function drm_plane_from_index() Chandra Konduru
@ 2015-04-10  0:36   ` Chandra Konduru
  2015-04-10  6:59     ` Daniel Vetter
  0 siblings, 1 reply; 54+ messages in thread
From: Chandra Konduru @ 2015-04-10  0:36 UTC (permalink / raw)
  To: intel-gfx; +Cc: ander.conselvan.de.oliveira, daniel.vetter, dri-devel

Adding drm helper function to return plane pointer from index where
index is a returned by drm_plane_index.

v2:
-avoided nested loop by adding loop count (Daniel)

v3:
-updated patch header prefix to 'drm' (Matt)

v4:
-fixed a kerneldoc issue (kbuild-internal)

Cc: dri-devel@lists.freedesktop.org

Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
---
 drivers/gpu/drm/drm_crtc.c |   23 +++++++++++++++++++++++
 include/drm/drm_crtc.h     |    1 +
 2 files changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index d576a4d..ad4d9ae 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1289,6 +1289,29 @@ unsigned int drm_plane_index(struct drm_plane *plane)
 EXPORT_SYMBOL(drm_plane_index);
 
 /**
+ * drm_plane_from_index - find the registered plane at an index
+ * @dev: DRM device
+ * @idx: index of registered plane to find for
+ *
+ * Given a plane index, return the registered plane from DRM device's
+ * list of planes with matching index.
+ */
+struct drm_plane *
+drm_plane_from_index(struct drm_device *dev, int idx)
+{
+	struct drm_plane *plane;
+	unsigned int i = 0;
+
+	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+		if (i == idx)
+			return plane;
+		i++;
+	}
+	return NULL;
+}
+EXPORT_SYMBOL(drm_plane_from_index);
+
+/**
  * drm_plane_force_disable - Forcibly disable a plane
  * @plane: plane to disable
  *
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 7b5c661..6b30036 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1264,6 +1264,7 @@ extern int drm_plane_init(struct drm_device *dev,
 			  bool is_primary);
 extern void drm_plane_cleanup(struct drm_plane *plane);
 extern unsigned int drm_plane_index(struct drm_plane *plane);
+extern struct drm_plane * drm_plane_from_index(struct drm_device *dev, int idx);
 extern void drm_plane_force_disable(struct drm_plane *plane);
 extern int drm_plane_check_pixel_format(const struct drm_plane *plane,
 					u32 format);
-- 
1.7.9.5

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

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

* Re: [PATCH 01/14] drm: Adding drm helper function drm_plane_from_index().
  2015-04-10  0:36   ` Chandra Konduru
@ 2015-04-10  6:59     ` Daniel Vetter
  2015-04-10 16:30       ` Konduru, Chandra
  0 siblings, 1 reply; 54+ messages in thread
From: Daniel Vetter @ 2015-04-10  6:59 UTC (permalink / raw)
  To: Chandra Konduru
  Cc: ander.conselvan.de.oliveira, intel-gfx, dri-devel, daniel.vetter

On Thu, Apr 09, 2015 at 05:36:21PM -0700, Chandra Konduru wrote:
> Adding drm helper function to return plane pointer from index where
> index is a returned by drm_plane_index.
> 
> v2:
> -avoided nested loop by adding loop count (Daniel)
> 
> v3:
> -updated patch header prefix to 'drm' (Matt)
> 
> v4:
> -fixed a kerneldoc issue (kbuild-internal)
> 
> Cc: dri-devel@lists.freedesktop.org
> 
> Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>

Applied with Dave's irc-ack. btw when resending patches please pick up r-b
tags so I don't have to hunt around on the m-l to find them.

Thanks, Daniel

> ---
>  drivers/gpu/drm/drm_crtc.c |   23 +++++++++++++++++++++++
>  include/drm/drm_crtc.h     |    1 +
>  2 files changed, 24 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index d576a4d..ad4d9ae 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -1289,6 +1289,29 @@ unsigned int drm_plane_index(struct drm_plane *plane)
>  EXPORT_SYMBOL(drm_plane_index);
>  
>  /**
> + * drm_plane_from_index - find the registered plane at an index
> + * @dev: DRM device
> + * @idx: index of registered plane to find for
> + *
> + * Given a plane index, return the registered plane from DRM device's
> + * list of planes with matching index.
> + */
> +struct drm_plane *
> +drm_plane_from_index(struct drm_device *dev, int idx)
> +{
> +	struct drm_plane *plane;
> +	unsigned int i = 0;
> +
> +	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
> +		if (i == idx)
> +			return plane;
> +		i++;
> +	}
> +	return NULL;
> +}
> +EXPORT_SYMBOL(drm_plane_from_index);
> +
> +/**
>   * drm_plane_force_disable - Forcibly disable a plane
>   * @plane: plane to disable
>   *
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index 7b5c661..6b30036 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -1264,6 +1264,7 @@ extern int drm_plane_init(struct drm_device *dev,
>  			  bool is_primary);
>  extern void drm_plane_cleanup(struct drm_plane *plane);
>  extern unsigned int drm_plane_index(struct drm_plane *plane);
> +extern struct drm_plane * drm_plane_from_index(struct drm_device *dev, int idx);
>  extern void drm_plane_force_disable(struct drm_plane *plane);
>  extern int drm_plane_check_pixel_format(const struct drm_plane *plane,
>  					u32 format);
> -- 
> 1.7.9.5
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 00/14] skylake display scalers
  2015-04-07 22:28 [PATCH 00/14] skylake display scalers Chandra Konduru
                   ` (14 preceding siblings ...)
  2015-04-09 21:53 ` [PATCH 00/14] skylake display scalers Matt Roper
@ 2015-04-10  9:34 ` Daniel Vetter
  2015-04-10 16:29   ` Konduru, Chandra
  15 siblings, 1 reply; 54+ messages in thread
From: Daniel Vetter @ 2015-04-10  9:34 UTC (permalink / raw)
  To: Chandra Konduru; +Cc: ander.conselvan.de.oliveira, intel-gfx, daniel.vetter

On Tue, Apr 07, 2015 at 03:28:33PM -0700, Chandra Konduru wrote:
> Primary changes in this version are:
> 1) Moved num_scalers to crtc
> 2) Changed src/dst rect ranges to #defines
> 3) Dropped scaling ratios from state instead calculating when needed
> 4) Dropped filter from scaler
> 5) Squashed helper functions from standalone patches into patch where 1st used
> 6) Kept sprite src tect in 16.16 format
> 
> Though changes are minor but they got sprinkled into multiple patches.
> 
> Sending full patch series for completeness. Individual patch headers
> have additional details on changes. This series should cleanly
> merge to latest drm-intel-nighly.
> 
> Chandra Konduru (14):
>   drm: Adding drm helper function drm_plane_from_index().
>   drm/i915: Register definitions for skylake scalers
>   drm/i915: skylake scaler structure definitions
>   drm/i915: Initialize plane colorkey to NONE
>   drm/i915: Initialize skylake scalers
>   drm/i915: Keep sprite plane src rect in 16.16 format
>   drm/i915: Dump scaler_state too as part of dumping crtc_state
>   drm/i915: Preserve scaler state when clearing crtc_state
>   drm/i915: setup scalers for crtc_compute_config
>   drm/i915: Ensure setting up scalers into staged crtc_state
>   drm/i915: copy staged scaler state from drm state to crtc->config.
>   drm/i915: skylake panel fitting using shared scalers
>   drm/i915: skylake primary plane scaling using shared scalers
>   drm/i915: skylake sprite plane scaling using shared scalers

Which igt do cover plane scaling? Do we have enough test coverage already
or have a missed the igt patch series for this feature work?
-Daniel

> 
>  drivers/gpu/drm/drm_crtc.c           |   22 ++
>  drivers/gpu/drm/i915/i915_reg.h      |  115 +++++++++
>  drivers/gpu/drm/i915/intel_atomic.c  |  163 +++++++++++++
>  drivers/gpu/drm/i915/intel_display.c |  441 +++++++++++++++++++++++++++++++---
>  drivers/gpu/drm/i915/intel_dp.c      |    8 +
>  drivers/gpu/drm/i915/intel_drv.h     |   76 ++++++
>  drivers/gpu/drm/i915/intel_sprite.c  |   83 +++++--
>  include/drm/drm_crtc.h               |    1 +
>  8 files changed, 855 insertions(+), 54 deletions(-)
> 
> -- 
> 1.7.9.5
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 00/14] skylake display scalers
  2015-04-10  9:34 ` Daniel Vetter
@ 2015-04-10 16:29   ` Konduru, Chandra
  0 siblings, 0 replies; 54+ messages in thread
From: Konduru, Chandra @ 2015-04-10 16:29 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Conselvan De Oliveira, Ander, intel-gfx, Wood, Thomas, Vetter, Daniel



> -----Original Message-----
> From: Daniel Vetter [mailto:daniel.vetter@ffwll.ch] On Behalf Of Daniel Vetter
> Sent: Friday, April 10, 2015 2:34 AM
> To: Konduru, Chandra
> Cc: intel-gfx@lists.freedesktop.org; Conselvan De Oliveira, Ander; Vetter, Daniel
> Subject: Re: [Intel-gfx] [PATCH 00/14] skylake display scalers
> 
> On Tue, Apr 07, 2015 at 03:28:33PM -0700, Chandra Konduru wrote:
> > Primary changes in this version are:
> > 1) Moved num_scalers to crtc
> > 2) Changed src/dst rect ranges to #defines
> > 3) Dropped scaling ratios from state instead calculating when needed
> > 4) Dropped filter from scaler
> > 5) Squashed helper functions from standalone patches into patch where
> > 1st used
> > 6) Kept sprite src tect in 16.16 format
> >
> > Though changes are minor but they got sprinkled into multiple patches.
> >
> > Sending full patch series for completeness. Individual patch headers
> > have additional details on changes. This series should cleanly merge
> > to latest drm-intel-nighly.
> >
> > Chandra Konduru (14):
> >   drm: Adding drm helper function drm_plane_from_index().
> >   drm/i915: Register definitions for skylake scalers
> >   drm/i915: skylake scaler structure definitions
> >   drm/i915: Initialize plane colorkey to NONE
> >   drm/i915: Initialize skylake scalers
> >   drm/i915: Keep sprite plane src rect in 16.16 format
> >   drm/i915: Dump scaler_state too as part of dumping crtc_state
> >   drm/i915: Preserve scaler state when clearing crtc_state
> >   drm/i915: setup scalers for crtc_compute_config
> >   drm/i915: Ensure setting up scalers into staged crtc_state
> >   drm/i915: copy staged scaler state from drm state to crtc->config.
> >   drm/i915: skylake panel fitting using shared scalers
> >   drm/i915: skylake primary plane scaling using shared scalers
> >   drm/i915: skylake sprite plane scaling using shared scalers
> 
> Which igt do cover plane scaling? Do we have enough test coverage already or
> have a missed the igt patch series for this feature work?
> -Daniel
Earlier I submitted igt patch (2 patches) series with two kms tests:
kms_plane_scaling - to cover various plane scaling scaling
kms_panel_fitting - to cover panel fitting and also panel fitting along with plane scaling
> 
> >
> >  drivers/gpu/drm/drm_crtc.c           |   22 ++
> >  drivers/gpu/drm/i915/i915_reg.h      |  115 +++++++++
> >  drivers/gpu/drm/i915/intel_atomic.c  |  163 +++++++++++++
> > drivers/gpu/drm/i915/intel_display.c |  441
> +++++++++++++++++++++++++++++++---
> >  drivers/gpu/drm/i915/intel_dp.c      |    8 +
> >  drivers/gpu/drm/i915/intel_drv.h     |   76 ++++++
> >  drivers/gpu/drm/i915/intel_sprite.c  |   83 +++++--
> >  include/drm/drm_crtc.h               |    1 +
> >  8 files changed, 855 insertions(+), 54 deletions(-)
> >
> > --
> > 1.7.9.5
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 01/14] drm: Adding drm helper function drm_plane_from_index().
  2015-04-10  6:59     ` Daniel Vetter
@ 2015-04-10 16:30       ` Konduru, Chandra
  0 siblings, 0 replies; 54+ messages in thread
From: Konduru, Chandra @ 2015-04-10 16:30 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Conselvan De Oliveira, Ander, intel-gfx, dri-devel, Vetter, Daniel



> -----Original Message-----
> From: Daniel Vetter [mailto:daniel.vetter@ffwll.ch] On Behalf Of Daniel Vetter
> Sent: Friday, April 10, 2015 12:00 AM
> To: Konduru, Chandra
> Cc: intel-gfx@lists.freedesktop.org; Conselvan De Oliveira, Ander; Vetter,
> Daniel; dri-devel@lists.freedesktop.org
> Subject: Re: [Intel-gfx] [PATCH 01/14] drm: Adding drm helper function
> drm_plane_from_index().
> 
> On Thu, Apr 09, 2015 at 05:36:21PM -0700, Chandra Konduru wrote:
> > Adding drm helper function to return plane pointer from index where
> > index is a returned by drm_plane_index.
> >
> > v2:
> > -avoided nested loop by adding loop count (Daniel)
> >
> > v3:
> > -updated patch header prefix to 'drm' (Matt)
> >
> > v4:
> > -fixed a kerneldoc issue (kbuild-internal)
> >
> > Cc: dri-devel@lists.freedesktop.org
> >
> > Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
> 
> Applied with Dave's irc-ack. btw when resending patches please pick up r-b tags
> so I don't have to hunt around on the m-l to find them.
Sure, will do.
> 
> Thanks, Daniel
> 
> > ---
> >  drivers/gpu/drm/drm_crtc.c |   23 +++++++++++++++++++++++
> >  include/drm/drm_crtc.h     |    1 +
> >  2 files changed, 24 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> > index d576a4d..ad4d9ae 100644
> > --- a/drivers/gpu/drm/drm_crtc.c
> > +++ b/drivers/gpu/drm/drm_crtc.c
> > @@ -1289,6 +1289,29 @@ unsigned int drm_plane_index(struct drm_plane
> > *plane)  EXPORT_SYMBOL(drm_plane_index);
> >
> >  /**
> > + * drm_plane_from_index - find the registered plane at an index
> > + * @dev: DRM device
> > + * @idx: index of registered plane to find for
> > + *
> > + * Given a plane index, return the registered plane from DRM device's
> > + * list of planes with matching index.
> > + */
> > +struct drm_plane *
> > +drm_plane_from_index(struct drm_device *dev, int idx) {
> > +	struct drm_plane *plane;
> > +	unsigned int i = 0;
> > +
> > +	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
> > +		if (i == idx)
> > +			return plane;
> > +		i++;
> > +	}
> > +	return NULL;
> > +}
> > +EXPORT_SYMBOL(drm_plane_from_index);
> > +
> > +/**
> >   * drm_plane_force_disable - Forcibly disable a plane
> >   * @plane: plane to disable
> >   *
> > diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index
> > 7b5c661..6b30036 100644
> > --- a/include/drm/drm_crtc.h
> > +++ b/include/drm/drm_crtc.h
> > @@ -1264,6 +1264,7 @@ extern int drm_plane_init(struct drm_device *dev,
> >  			  bool is_primary);
> >  extern void drm_plane_cleanup(struct drm_plane *plane);  extern
> > unsigned int drm_plane_index(struct drm_plane *plane);
> > +extern struct drm_plane * drm_plane_from_index(struct drm_device
> > +*dev, int idx);
> >  extern void drm_plane_force_disable(struct drm_plane *plane);  extern
> > int drm_plane_check_pixel_format(const struct drm_plane *plane,
> >  					u32 format);
> > --
> > 1.7.9.5
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 13/14] drm/i915: skylake primary plane scaling using shared scalers
  2015-04-09 22:14     ` Konduru, Chandra
@ 2015-04-13  9:46       ` Daniel Vetter
  0 siblings, 0 replies; 54+ messages in thread
From: Daniel Vetter @ 2015-04-13  9:46 UTC (permalink / raw)
  To: Konduru, Chandra; +Cc: Vetter, Daniel, intel-gfx, Conselvan De Oliveira, Ander

On Thu, Apr 09, 2015 at 10:14:36PM +0000, Konduru, Chandra wrote:
> 
> 
> > -----Original Message-----
> > From: Roper, Matthew D
> > Sent: Thursday, April 09, 2015 2:52 PM
> > To: Konduru, Chandra
> > Cc: intel-gfx@lists.freedesktop.org; Vetter, Daniel; Conselvan De Oliveira, Ander
> > Subject: Re: [PATCH 13/14] drm/i915: skylake primary plane scaling using shared
> > scalers
> > 
> > On Tue, Apr 07, 2015 at 03:28:46PM -0700, Chandra Konduru wrote:
> > > This patch enables skylake primary plane scaling using shared scalers
> > > atomic desgin.
> > >
> > > v2:
> > > -use single copy of scaler limits (Matt)
> > >
> > > v3:
> > > -move detach_scalers to crtc commit path (Matt) -use values in
> > > plane_state->src as regular integers (me)
> > >
> > > v4:
> > > -changes to align with updated scaler structures (Matt, me) -keep
> > > plane src rect in 16.16 format (Matt, Daniel)
> > 
> > See comments on patch #6 that relate to this.  If you want to take the approach
> > here (perform the unshift in skl_update_plane) then you also need to do the
> > same for all other platforms (ivb, ilk, vlv, etc.).  But my suggestion on the other
> > patch (do the unshifting in commit_plane and leave skl_update_plane alone)
> > might be a bit simpler.
> 
> Above v4: comment is saying that the change done in v3 was undone to keep 
> primary_plane src rect in 16.16 format.
> 
> As I responded to your patch #6 comment, moving unshift hunk (which is for
> sprite plane) from #14 to #6 will avoid any potential bisect issue that you mentioned.
> 
> For other than skylake, primary planes platform level update functions doesn't use
> src_rect instead operate based on passed parameters which are in regular ints.
> Only for skylake primary plane update function, src rect is used for windowing,
> scaling purposes.

I merged up to patch 12, but this one here doesn't apply any more and I'm
not sure whether there's any changes still needed to it (it sounds like
not, but chasing that unshifting business is tricky). Chandra, can you
please resend rebased patches (with Matt's r-b added)?

Thanks, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 13/14] drm/i915: skylake primary plane scaling using shared scalers
  2015-04-07 22:28 ` [PATCH 13/14] drm/i915: skylake primary plane scaling " Chandra Konduru
  2015-04-09 21:51   ` Matt Roper
@ 2015-04-13 18:12   ` Daniel Vetter
  2015-04-13 18:18     ` Konduru, Chandra
  2015-04-14  7:00   ` Daniel Vetter
                     ` (2 subsequent siblings)
  4 siblings, 1 reply; 54+ messages in thread
From: Daniel Vetter @ 2015-04-13 18:12 UTC (permalink / raw)
  To: Chandra Konduru; +Cc: ander.conselvan.de.oliveira, intel-gfx, daniel.vetter

On Tue, Apr 07, 2015 at 03:28:46PM -0700, Chandra Konduru wrote:
> This patch enables skylake primary plane scaling using shared
> scalers atomic desgin.
> 
> v2:
> -use single copy of scaler limits (Matt)
> 
> v3:
> -move detach_scalers to crtc commit path (Matt)
> -use values in plane_state->src as regular integers (me)
> 
> v4:
> -changes to align with updated scaler structures (Matt, me)
> -keep plane src rect in 16.16 format (Matt, Daniel)
> 
> Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>

Ok there's a real functional conflict here now with 90/270 rotation. It's
big enough that imo we also need to add igt coverage to test
rotation+scaling together (the scaled plane setup is different from the
normal one, and we need to also make sure we scale correctly itself when
rotated).

Chandra can you please figure out with Sonika who can do this rebasing/igt
extension?

Thanks, Daniel

> ---
>  drivers/gpu/drm/i915/intel_atomic.c  |    5 +-
>  drivers/gpu/drm/i915/intel_display.c |   96 ++++++++++++++++++++++++++++++++--
>  drivers/gpu/drm/i915/intel_drv.h     |    1 +
>  drivers/gpu/drm/i915/intel_sprite.c  |    9 ++++
>  4 files changed, 105 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> index 2fc04ec..8f759c6 100644
> --- a/drivers/gpu/drm/i915/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> @@ -167,7 +167,7 @@ int intel_atomic_commit(struct drm_device *dev,
>  		plane->state->state = NULL;
>  	}
>  
> -	/* swap crtc_state */
> +	/* swap crtc_scaler_state */
>  	for (i = 0; i < dev->mode_config.num_crtc; i++) {
>  		struct drm_crtc *crtc = state->crtcs[i];
>  		if (!crtc) {
> @@ -176,6 +176,9 @@ int intel_atomic_commit(struct drm_device *dev,
>  
>  		to_intel_crtc(crtc)->config->scaler_state =
>  			to_intel_crtc_state(state->crtc_states[i])->scaler_state;
> +
> +		if (INTEL_INFO(dev)->gen >= 9)
> +			skl_detach_scalers(to_intel_crtc(crtc));
>  	}
>  
>  	drm_atomic_helper_commit_planes(dev, state);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index aa4da1f..c7ee232 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2978,6 +2978,14 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc,
>  	int pipe = intel_crtc->pipe;
>  	u32 plane_ctl, stride_div;
>  	unsigned long surf_addr;
> +	struct intel_crtc_state *crtc_state = intel_crtc->config;
> +	struct intel_plane_state *plane_state;
> +	int src_x = 0, src_y = 0, src_w = 0, src_h = 0;
> +	int dst_x = 0, dst_y = 0, dst_w = 0, dst_h = 0;
> +	int scaler_id = -1;
> +
> +	plane_state = crtc->primary ?
> +		to_intel_plane_state(crtc->primary->state) : NULL;
>  
>  	if (!intel_crtc->primary_enabled) {
>  		I915_WRITE(PLANE_CTL(pipe, 0), 0);
> @@ -3046,12 +3054,40 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc,
>  					       fb->pixel_format);
>  	surf_addr = intel_plane_obj_offset(to_intel_plane(crtc->primary), obj);
>  
> +	if (plane_state) {
> +		scaler_id = plane_state->scaler_id;
> +		src_x = plane_state->src.x1 >> 16;
> +		src_y = plane_state->src.y1 >> 16;
> +		src_w = drm_rect_width(&plane_state->src) >> 16;
> +		src_h = drm_rect_height(&plane_state->src) >> 16;
> +		dst_x = plane_state->dst.x1;
> +		dst_y = plane_state->dst.y1;
> +		dst_w = drm_rect_width(&plane_state->dst);
> +		dst_h = drm_rect_height(&plane_state->dst);
> +	}
> +
>  	I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
>  	I915_WRITE(PLANE_POS(pipe, 0), 0);
> +
> +	if (src_w && src_h && dst_w && dst_h && scaler_id >= 0) {
> +		uint32_t ps_ctrl = 0;
> +
> +		WARN_ON(x != src_x || y != src_y);
> +		ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(0) |
> +			crtc_state->scaler_state.scalers[scaler_id].mode;
> +		I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
> +		I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
> +		I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (dst_x << 16) | dst_y);
> +		I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id), (dst_w << 16) | dst_h);
> +
> +		I915_WRITE(PLANE_SIZE(pipe, 0), ((src_h - 1) << 16) | (src_w - 1));
> +	} else {
> +		I915_WRITE(PLANE_SIZE(pipe, 0),
> +			(intel_crtc->config->pipe_src_h - 1) << 16 |
> +			(intel_crtc->config->pipe_src_w - 1));
> +	}
> +
>  	I915_WRITE(PLANE_OFFSET(pipe, 0), (y << 16) | x);
> -	I915_WRITE(PLANE_SIZE(pipe, 0),
> -		   (intel_crtc->config->pipe_src_h - 1) << 16 |
> -		   (intel_crtc->config->pipe_src_w - 1));
>  	I915_WRITE(PLANE_STRIDE(pipe, 0), fb->pitches[0] / stride_div);
>  	I915_WRITE(PLANE_SURF(pipe, 0), surf_addr);
>  
> @@ -12778,6 +12814,36 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
>  	}
>  }
>  
> +int
> +skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state)
> +{
> +	int max_scale;
> +	struct drm_device *dev;
> +	struct drm_i915_private *dev_priv;
> +	int crtc_clock, cdclk;
> +
> +	if (!intel_crtc || !crtc_state)
> +		return DRM_PLANE_HELPER_NO_SCALING;
> +
> +	dev = intel_crtc->base.dev;
> +	dev_priv = dev->dev_private;
> +	crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
> +	cdclk = dev_priv->display.get_display_clock_speed(dev);
> +
> +	if (!crtc_clock || !cdclk)
> +		return DRM_PLANE_HELPER_NO_SCALING;
> +
> +	/*
> +	 * skl max scale is lower of:
> +	 *    close to 3 but not 3, -1 is for that purpose
> +	 *            or
> +	 *    cdclk/crtc_clock
> +	 */
> +	max_scale = min((1 << 16) * 3 - 1, (1 << 8) * ((cdclk << 8) / crtc_clock));
> +
> +	return max_scale;
> +}
> +
>  static int
>  intel_check_primary_plane(struct drm_plane *plane,
>  			  struct intel_plane_state *state)
> @@ -12786,19 +12852,29 @@ intel_check_primary_plane(struct drm_plane *plane,
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct drm_crtc *crtc = state->base.crtc;
>  	struct intel_crtc *intel_crtc;
> +	struct intel_crtc_state *crtc_state;
>  	struct drm_framebuffer *fb = state->base.fb;
>  	struct drm_rect *dest = &state->dst;
>  	struct drm_rect *src = &state->src;
>  	const struct drm_rect *clip = &state->clip;
> +	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
> +	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
>  	int ret;
>  
>  	crtc = crtc ? crtc : plane->crtc;
>  	intel_crtc = to_intel_crtc(crtc);
> +	crtc_state = state->base.state ?
> +		intel_atomic_get_crtc_state(state->base.state, intel_crtc) : NULL;
> +
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		min_scale = 1;
> +		max_scale = skl_max_scale(intel_crtc, crtc_state);
> +	}
>  
>  	ret = drm_plane_helper_check_update(plane, crtc, fb,
>  					    src, dest, clip,
> -					    DRM_PLANE_HELPER_NO_SCALING,
> -					    DRM_PLANE_HELPER_NO_SCALING,
> +					    min_scale,
> +					    max_scale,
>  					    false, true, &state->visible);
>  	if (ret)
>  		return ret;
> @@ -12842,6 +12918,13 @@ intel_check_primary_plane(struct drm_plane *plane,
>  			intel_crtc->atomic.update_wm = true;
>  	}
>  
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		ret = skl_update_scaler_users(intel_crtc, crtc_state,
> +			to_intel_plane(plane), state, 0);
> +		if (ret)
> +			return ret;
> +	}
> +
>  	return 0;
>  }
>  
> @@ -13021,6 +13104,9 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
>  
>  	primary->can_scale = false;
>  	primary->max_downscale = 1;
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		primary->can_scale = true;
> +	}
>  	state->scaler_id = -1;
>  	primary->pipe = pipe;
>  	primary->plane = pipe;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 7b28bff..0543150 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1125,6 +1125,7 @@ void skl_detach_scalers(struct intel_crtc *intel_crtc);
>  int skl_update_scaler_users(struct intel_crtc *intel_crtc,
>  	struct intel_crtc_state *crtc_state, struct intel_plane *intel_plane,
>  	struct intel_plane_state *plane_state, int force_detach);
> +int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state);
>  
>  unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
>  				     struct drm_i915_gem_object *obj);
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index c05fb36..955965c 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -1119,6 +1119,15 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
>  	}
>  
>  	intel_plane = to_intel_plane(plane);
> +
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		/* plane scaling and colorkey are mutually exclusive */
> +		if (to_intel_plane_state(plane->state)->scaler_id >= 0) {
> +			DRM_ERROR("colorkey not allowed with scaler\n");
> +			return -EINVAL;
> +		}
> +	}
> +
>  	intel_plane->ckey = *set;
>  
>  	/*
> -- 
> 1.7.9.5
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 13/14] drm/i915: skylake primary plane scaling using shared scalers
  2015-04-13 18:12   ` Daniel Vetter
@ 2015-04-13 18:18     ` Konduru, Chandra
  0 siblings, 0 replies; 54+ messages in thread
From: Konduru, Chandra @ 2015-04-13 18:18 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Conselvan De Oliveira, Ander, intel-gfx, Vetter, Daniel



> -----Original Message-----
> From: Daniel Vetter [mailto:daniel.vetter@ffwll.ch] On Behalf Of Daniel Vetter
> Sent: Monday, April 13, 2015 11:13 AM
> To: Konduru, Chandra
> Cc: intel-gfx@lists.freedesktop.org; Conselvan De Oliveira, Ander; Vetter, Daniel
> Subject: Re: [Intel-gfx] [PATCH 13/14] drm/i915: skylake primary plane scaling
> using shared scalers
> 
> On Tue, Apr 07, 2015 at 03:28:46PM -0700, Chandra Konduru wrote:
> > This patch enables skylake primary plane scaling using shared scalers
> > atomic desgin.
> >
> > v2:
> > -use single copy of scaler limits (Matt)
> >
> > v3:
> > -move detach_scalers to crtc commit path (Matt) -use values in
> > plane_state->src as regular integers (me)
> >
> > v4:
> > -changes to align with updated scaler structures (Matt, me) -keep
> > plane src rect in 16.16 format (Matt, Daniel)
> >
> > Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
> 
> Ok there's a real functional conflict here now with 90/270 rotation. It's big
> enough that imo we also need to add igt coverage to test
> rotation+scaling together (the scaled plane setup is different from the
> normal one, and we need to also make sure we scale correctly itself when
> rotated).
> 
> Chandra can you please figure out with Sonika who can do this rebasing/igt
> extension?

To give some context, this was one of the reasons I gave heads up to Sonika 
to rebase 90/270 on top of scalers but looks they weren't.

Agree that we need igt for rotation+scaling too. In current kms_plane_scaling
didn't planned to cover 90/270 for the same reason that igt for 90/270 taking 
care of that.

Sure, will sync up offline with Sonika and get back on the last two patches and
igt too.

> 
> Thanks, Daniel
> 
> > ---
> >  drivers/gpu/drm/i915/intel_atomic.c  |    5 +-
> >  drivers/gpu/drm/i915/intel_display.c |   96
> ++++++++++++++++++++++++++++++++--
> >  drivers/gpu/drm/i915/intel_drv.h     |    1 +
> >  drivers/gpu/drm/i915/intel_sprite.c  |    9 ++++
> >  4 files changed, 105 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_atomic.c
> > b/drivers/gpu/drm/i915/intel_atomic.c
> > index 2fc04ec..8f759c6 100644
> > --- a/drivers/gpu/drm/i915/intel_atomic.c
> > +++ b/drivers/gpu/drm/i915/intel_atomic.c
> > @@ -167,7 +167,7 @@ int intel_atomic_commit(struct drm_device *dev,
> >  		plane->state->state = NULL;
> >  	}
> >
> > -	/* swap crtc_state */
> > +	/* swap crtc_scaler_state */
> >  	for (i = 0; i < dev->mode_config.num_crtc; i++) {
> >  		struct drm_crtc *crtc = state->crtcs[i];
> >  		if (!crtc) {
> > @@ -176,6 +176,9 @@ int intel_atomic_commit(struct drm_device *dev,
> >
> >  		to_intel_crtc(crtc)->config->scaler_state =
> >  			to_intel_crtc_state(state->crtc_states[i])->scaler_state;
> > +
> > +		if (INTEL_INFO(dev)->gen >= 9)
> > +			skl_detach_scalers(to_intel_crtc(crtc));
> >  	}
> >
> >  	drm_atomic_helper_commit_planes(dev, state); diff --git
> > a/drivers/gpu/drm/i915/intel_display.c
> > b/drivers/gpu/drm/i915/intel_display.c
> > index aa4da1f..c7ee232 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -2978,6 +2978,14 @@ static void skylake_update_primary_plane(struct
> drm_crtc *crtc,
> >  	int pipe = intel_crtc->pipe;
> >  	u32 plane_ctl, stride_div;
> >  	unsigned long surf_addr;
> > +	struct intel_crtc_state *crtc_state = intel_crtc->config;
> > +	struct intel_plane_state *plane_state;
> > +	int src_x = 0, src_y = 0, src_w = 0, src_h = 0;
> > +	int dst_x = 0, dst_y = 0, dst_w = 0, dst_h = 0;
> > +	int scaler_id = -1;
> > +
> > +	plane_state = crtc->primary ?
> > +		to_intel_plane_state(crtc->primary->state) : NULL;
> >
> >  	if (!intel_crtc->primary_enabled) {
> >  		I915_WRITE(PLANE_CTL(pipe, 0), 0);
> > @@ -3046,12 +3054,40 @@ static void skylake_update_primary_plane(struct
> drm_crtc *crtc,
> >  					       fb->pixel_format);
> >  	surf_addr = intel_plane_obj_offset(to_intel_plane(crtc->primary),
> > obj);
> >
> > +	if (plane_state) {
> > +		scaler_id = plane_state->scaler_id;
> > +		src_x = plane_state->src.x1 >> 16;
> > +		src_y = plane_state->src.y1 >> 16;
> > +		src_w = drm_rect_width(&plane_state->src) >> 16;
> > +		src_h = drm_rect_height(&plane_state->src) >> 16;
> > +		dst_x = plane_state->dst.x1;
> > +		dst_y = plane_state->dst.y1;
> > +		dst_w = drm_rect_width(&plane_state->dst);
> > +		dst_h = drm_rect_height(&plane_state->dst);
> > +	}
> > +
> >  	I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
> >  	I915_WRITE(PLANE_POS(pipe, 0), 0);
> > +
> > +	if (src_w && src_h && dst_w && dst_h && scaler_id >= 0) {
> > +		uint32_t ps_ctrl = 0;
> > +
> > +		WARN_ON(x != src_x || y != src_y);
> > +		ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(0) |
> > +			crtc_state->scaler_state.scalers[scaler_id].mode;
> > +		I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
> > +		I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
> > +		I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (dst_x << 16) |
> dst_y);
> > +		I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id), (dst_w << 16) |
> dst_h);
> > +
> > +		I915_WRITE(PLANE_SIZE(pipe, 0), ((src_h - 1) << 16) | (src_w -
> 1));
> > +	} else {
> > +		I915_WRITE(PLANE_SIZE(pipe, 0),
> > +			(intel_crtc->config->pipe_src_h - 1) << 16 |
> > +			(intel_crtc->config->pipe_src_w - 1));
> > +	}
> > +
> >  	I915_WRITE(PLANE_OFFSET(pipe, 0), (y << 16) | x);
> > -	I915_WRITE(PLANE_SIZE(pipe, 0),
> > -		   (intel_crtc->config->pipe_src_h - 1) << 16 |
> > -		   (intel_crtc->config->pipe_src_w - 1));
> >  	I915_WRITE(PLANE_STRIDE(pipe, 0), fb->pitches[0] / stride_div);
> >  	I915_WRITE(PLANE_SURF(pipe, 0), surf_addr);
> >
> > @@ -12778,6 +12814,36 @@ intel_cleanup_plane_fb(struct drm_plane
> *plane,
> >  	}
> >  }
> >
> > +int
> > +skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state
> > +*crtc_state) {
> > +	int max_scale;
> > +	struct drm_device *dev;
> > +	struct drm_i915_private *dev_priv;
> > +	int crtc_clock, cdclk;
> > +
> > +	if (!intel_crtc || !crtc_state)
> > +		return DRM_PLANE_HELPER_NO_SCALING;
> > +
> > +	dev = intel_crtc->base.dev;
> > +	dev_priv = dev->dev_private;
> > +	crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
> > +	cdclk = dev_priv->display.get_display_clock_speed(dev);
> > +
> > +	if (!crtc_clock || !cdclk)
> > +		return DRM_PLANE_HELPER_NO_SCALING;
> > +
> > +	/*
> > +	 * skl max scale is lower of:
> > +	 *    close to 3 but not 3, -1 is for that purpose
> > +	 *            or
> > +	 *    cdclk/crtc_clock
> > +	 */
> > +	max_scale = min((1 << 16) * 3 - 1, (1 << 8) * ((cdclk << 8) /
> > +crtc_clock));
> > +
> > +	return max_scale;
> > +}
> > +
> >  static int
> >  intel_check_primary_plane(struct drm_plane *plane,
> >  			  struct intel_plane_state *state) @@ -12786,19
> +12852,29 @@
> > intel_check_primary_plane(struct drm_plane *plane,
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> >  	struct drm_crtc *crtc = state->base.crtc;
> >  	struct intel_crtc *intel_crtc;
> > +	struct intel_crtc_state *crtc_state;
> >  	struct drm_framebuffer *fb = state->base.fb;
> >  	struct drm_rect *dest = &state->dst;
> >  	struct drm_rect *src = &state->src;
> >  	const struct drm_rect *clip = &state->clip;
> > +	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
> > +	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
> >  	int ret;
> >
> >  	crtc = crtc ? crtc : plane->crtc;
> >  	intel_crtc = to_intel_crtc(crtc);
> > +	crtc_state = state->base.state ?
> > +		intel_atomic_get_crtc_state(state->base.state, intel_crtc) :
> NULL;
> > +
> > +	if (INTEL_INFO(dev)->gen >= 9) {
> > +		min_scale = 1;
> > +		max_scale = skl_max_scale(intel_crtc, crtc_state);
> > +	}
> >
> >  	ret = drm_plane_helper_check_update(plane, crtc, fb,
> >  					    src, dest, clip,
> > -					    DRM_PLANE_HELPER_NO_SCALING,
> > -					    DRM_PLANE_HELPER_NO_SCALING,
> > +					    min_scale,
> > +					    max_scale,
> >  					    false, true, &state->visible);
> >  	if (ret)
> >  		return ret;
> > @@ -12842,6 +12918,13 @@ intel_check_primary_plane(struct drm_plane
> *plane,
> >  			intel_crtc->atomic.update_wm = true;
> >  	}
> >
> > +	if (INTEL_INFO(dev)->gen >= 9) {
> > +		ret = skl_update_scaler_users(intel_crtc, crtc_state,
> > +			to_intel_plane(plane), state, 0);
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> >  	return 0;
> >  }
> >
> > @@ -13021,6 +13104,9 @@ static struct drm_plane
> > *intel_primary_plane_create(struct drm_device *dev,
> >
> >  	primary->can_scale = false;
> >  	primary->max_downscale = 1;
> > +	if (INTEL_INFO(dev)->gen >= 9) {
> > +		primary->can_scale = true;
> > +	}
> >  	state->scaler_id = -1;
> >  	primary->pipe = pipe;
> >  	primary->plane = pipe;
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h
> > b/drivers/gpu/drm/i915/intel_drv.h
> > index 7b28bff..0543150 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -1125,6 +1125,7 @@ void skl_detach_scalers(struct intel_crtc
> > *intel_crtc);  int skl_update_scaler_users(struct intel_crtc *intel_crtc,
> >  	struct intel_crtc_state *crtc_state, struct intel_plane *intel_plane,
> >  	struct intel_plane_state *plane_state, int force_detach);
> > +int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state
> > +*crtc_state);
> >
> >  unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
> >  				     struct drm_i915_gem_object *obj); diff --git
> > a/drivers/gpu/drm/i915/intel_sprite.c
> > b/drivers/gpu/drm/i915/intel_sprite.c
> > index c05fb36..955965c 100644
> > --- a/drivers/gpu/drm/i915/intel_sprite.c
> > +++ b/drivers/gpu/drm/i915/intel_sprite.c
> > @@ -1119,6 +1119,15 @@ int intel_sprite_set_colorkey(struct drm_device
> *dev, void *data,
> >  	}
> >
> >  	intel_plane = to_intel_plane(plane);
> > +
> > +	if (INTEL_INFO(dev)->gen >= 9) {
> > +		/* plane scaling and colorkey are mutually exclusive */
> > +		if (to_intel_plane_state(plane->state)->scaler_id >= 0) {
> > +			DRM_ERROR("colorkey not allowed with scaler\n");
> > +			return -EINVAL;
> > +		}
> > +	}
> > +
> >  	intel_plane->ckey = *set;
> >
> >  	/*
> > --
> > 1.7.9.5
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 13/14] drm/i915: skylake primary plane scaling using shared scalers
  2015-04-07 22:28 ` [PATCH 13/14] drm/i915: skylake primary plane scaling " Chandra Konduru
  2015-04-09 21:51   ` Matt Roper
  2015-04-13 18:12   ` Daniel Vetter
@ 2015-04-14  7:00   ` Daniel Vetter
  2015-04-15 22:14   ` Chandra Konduru
  2015-04-27 20:48   ` Chandra Konduru
  4 siblings, 0 replies; 54+ messages in thread
From: Daniel Vetter @ 2015-04-14  7:00 UTC (permalink / raw)
  To: Chandra Konduru; +Cc: ander.conselvan.de.oliveira, intel-gfx, daniel.vetter

On Tue, Apr 07, 2015 at 03:28:46PM -0700, Chandra Konduru wrote:
> This patch enables skylake primary plane scaling using shared
> scalers atomic desgin.
> 
> v2:
> -use single copy of scaler limits (Matt)
> 
> v3:
> -move detach_scalers to crtc commit path (Matt)
> -use values in plane_state->src as regular integers (me)
> 
> v4:
> -changes to align with updated scaler structures (Matt, me)
> -keep plane src rect in 16.16 format (Matt, Daniel)
> 
> Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_atomic.c  |    5 +-
>  drivers/gpu/drm/i915/intel_display.c |   96 ++++++++++++++++++++++++++++++++--
>  drivers/gpu/drm/i915/intel_drv.h     |    1 +
>  drivers/gpu/drm/i915/intel_sprite.c  |    9 ++++
>  4 files changed, 105 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> index 2fc04ec..8f759c6 100644
> --- a/drivers/gpu/drm/i915/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> @@ -167,7 +167,7 @@ int intel_atomic_commit(struct drm_device *dev,
>  		plane->state->state = NULL;
>  	}
>  
> -	/* swap crtc_state */
> +	/* swap crtc_scaler_state */
>  	for (i = 0; i < dev->mode_config.num_crtc; i++) {
>  		struct drm_crtc *crtc = state->crtcs[i];
>  		if (!crtc) {
> @@ -176,6 +176,9 @@ int intel_atomic_commit(struct drm_device *dev,
>  
>  		to_intel_crtc(crtc)->config->scaler_state =
>  			to_intel_crtc_state(state->crtc_states[i])->scaler_state;
> +
> +		if (INTEL_INFO(dev)->gen >= 9)
> +			skl_detach_scalers(to_intel_crtc(crtc));
>  	}
>  
>  	drm_atomic_helper_commit_planes(dev, state);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index aa4da1f..c7ee232 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2978,6 +2978,14 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc,

And one real piece of review feedback: This function is now definitely too
long. Same holds for the sprite update function below.

Can you (or Sonika) please follow up with a few patches to extract
subroutines to make this a bit easier to read?

Thanks, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 13/14] drm/i915: skylake primary plane scaling using shared scalers
  2015-04-07 22:28 ` [PATCH 13/14] drm/i915: skylake primary plane scaling " Chandra Konduru
                     ` (2 preceding siblings ...)
  2015-04-14  7:00   ` Daniel Vetter
@ 2015-04-15 22:14   ` Chandra Konduru
  2015-04-15 23:08     ` Konduru, Chandra
                       ` (3 more replies)
  2015-04-27 20:48   ` Chandra Konduru
  4 siblings, 4 replies; 54+ messages in thread
From: Chandra Konduru @ 2015-04-15 22:14 UTC (permalink / raw)
  To: intel-gfx; +Cc: daniel.vetter, ander.conselvan.de.oliveira

This patch enables skylake primary plane scaling using shared
scalers atomic desgin.

v2:
-use single copy of scaler limits (Matt)

v3:
-move detach_scalers to crtc commit path (Matt)
-use values in plane_state->src as regular integers (me)

v4:
-changes to align with updated scaler structures (Matt, me)
-keep plane src rect in 16.16 format (Matt, Daniel)

v5:
-Rebased on top of 90/270 rotation changes (me)
-Fixed an issue introduced by 90/270 changes where plane programming
 is using drm_plane->state rect instead of intel_plane->state rect.
 This change also required for scaling to work properly. (me)
-With 90/270, updated limits to cover both portrait and landscape usages (me)
-Refactored skylake_update_primary_plane to reduce its size (Daniel)
 Added helper functions for refactoring are comprehended enough to be
 used for skylake_update_plane (for sprite) too. One stop towards
 having single function for all planes.

Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Testcase: kms_plane_scaling
---
 drivers/gpu/drm/i915/intel_atomic.c  |    5 +-
 drivers/gpu/drm/i915/intel_display.c |  261 +++++++++++++++++++++++++---------
 drivers/gpu/drm/i915/intel_drv.h     |    8 +-
 drivers/gpu/drm/i915/intel_sprite.c  |    9 ++
 4 files changed, 213 insertions(+), 70 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 3c4b7cd..cb6d5f2 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -169,7 +169,7 @@ int intel_atomic_commit(struct drm_device *dev,
 		plane->state->state = NULL;
 	}
 
-	/* swap crtc_state */
+	/* swap crtc_scaler_state */
 	for (i = 0; i < dev->mode_config.num_crtc; i++) {
 		struct drm_crtc *crtc = state->crtcs[i];
 		if (!crtc) {
@@ -178,6 +178,9 @@ int intel_atomic_commit(struct drm_device *dev,
 
 		to_intel_crtc(crtc)->config->scaler_state =
 			to_intel_crtc_state(state->crtc_states[i])->scaler_state;
+
+		if (INTEL_INFO(dev)->gen >= 9)
+			skl_detach_scalers(to_intel_crtc(crtc));
 	}
 
 	drm_atomic_helper_commit_planes(dev, state);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 5f7a40f..7f3ae8e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2960,126 +2960,199 @@ void skl_detach_scalers(struct intel_crtc *intel_crtc)
 	}
 }
 
-static void skylake_update_primary_plane(struct drm_crtc *crtc,
-					 struct drm_framebuffer *fb,
-					 int x, int y)
+u32 skl_plane_ctl_format(uint32_t pixel_format)
 {
-	struct drm_device *dev = crtc->dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct drm_i915_gem_object *obj;
-	int pipe = intel_crtc->pipe;
-	u32 plane_ctl, stride_div, stride;
-	u32 tile_height, plane_offset, plane_size;
-	unsigned int rotation;
-	int x_offset, y_offset;
-	unsigned long surf_addr;
-	struct drm_plane *plane;
-
-	if (!intel_crtc->primary_enabled) {
-		I915_WRITE(PLANE_CTL(pipe, 0), 0);
-		I915_WRITE(PLANE_SURF(pipe, 0), 0);
-		POSTING_READ(PLANE_CTL(pipe, 0));
-		return;
-	}
-
-	plane_ctl = PLANE_CTL_ENABLE |
-		    PLANE_CTL_PIPE_GAMMA_ENABLE |
-		    PLANE_CTL_PIPE_CSC_ENABLE;
-
-	switch (fb->pixel_format) {
+	u32 plane_ctl_format = 0;
+	switch (pixel_format) {
 	case DRM_FORMAT_RGB565:
-		plane_ctl |= PLANE_CTL_FORMAT_RGB_565;
-		break;
-	case DRM_FORMAT_XRGB8888:
-		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
-		break;
-	case DRM_FORMAT_ARGB8888:
-		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
-		plane_ctl |= PLANE_CTL_ALPHA_SW_PREMULTIPLY;
+		plane_ctl_format = PLANE_CTL_FORMAT_RGB_565;
 		break;
 	case DRM_FORMAT_XBGR8888:
-		plane_ctl |= PLANE_CTL_ORDER_RGBX;
-		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
+		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
 		break;
+	case DRM_FORMAT_XRGB8888:
+		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888;
+		break;
+	/*
+	 * XXX: For ARBG/ABGR formats we default to expecting scanout buffers
+	 * to be already pre-multiplied. We need to add a knob (or a different
+	 * DRM_FORMAT) for user-space to configure that.
+	 */
 	case DRM_FORMAT_ABGR8888:
-		plane_ctl |= PLANE_CTL_ORDER_RGBX;
-		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
-		plane_ctl |= PLANE_CTL_ALPHA_SW_PREMULTIPLY;
+		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX |
+			PLANE_CTL_ALPHA_SW_PREMULTIPLY;
+		break;
+	case DRM_FORMAT_ARGB8888:
+		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 |
+			PLANE_CTL_ALPHA_SW_PREMULTIPLY;
 		break;
 	case DRM_FORMAT_XRGB2101010:
-		plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010;
+		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_2101010;
 		break;
 	case DRM_FORMAT_XBGR2101010:
-		plane_ctl |= PLANE_CTL_ORDER_RGBX;
-		plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010;
+		plane_ctl_format = PLANE_CTL_ORDER_RGBX | PLANE_CTL_FORMAT_XRGB_2101010;
+		break;
+	case DRM_FORMAT_YUYV:
+		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV;
+		break;
+	case DRM_FORMAT_YVYU:
+		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU;
+		break;
+	case DRM_FORMAT_UYVY:
+		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY;
+		break;
+	case DRM_FORMAT_VYUY:
+		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
 		break;
 	default:
 		BUG();
 	}
+	return plane_ctl_format;
+}
 
-	switch (fb->modifier[0]) {
+u32 skl_plane_ctl_tiling(uint64_t fb_modifier)
+{
+	u32 plane_ctl_tiling = 0;
+	switch (fb_modifier) {
 	case DRM_FORMAT_MOD_NONE:
 		break;
 	case I915_FORMAT_MOD_X_TILED:
-		plane_ctl |= PLANE_CTL_TILED_X;
+		plane_ctl_tiling = PLANE_CTL_TILED_X;
 		break;
 	case I915_FORMAT_MOD_Y_TILED:
-		plane_ctl |= PLANE_CTL_TILED_Y;
+		plane_ctl_tiling = PLANE_CTL_TILED_Y;
 		break;
 	case I915_FORMAT_MOD_Yf_TILED:
-		plane_ctl |= PLANE_CTL_TILED_YF;
+		plane_ctl_tiling = PLANE_CTL_TILED_YF;
 		break;
 	default:
-		MISSING_CASE(fb->modifier[0]);
+		MISSING_CASE(fb_modifier);
 	}
+	return plane_ctl_tiling;
+}
 
-	plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
-
-	plane = crtc->primary;
-	rotation = plane->state->rotation;
+u32 skl_plane_ctl_rotation(unsigned int rotation)
+{
+	u32 plane_ctl_rotation = 0;
 	switch (rotation) {
+	case BIT(DRM_ROTATE_0):
+		break;
 	case BIT(DRM_ROTATE_90):
-		plane_ctl |= PLANE_CTL_ROTATE_90;
+		plane_ctl_rotation = PLANE_CTL_ROTATE_90;
 		break;
-
 	case BIT(DRM_ROTATE_180):
-		plane_ctl |= PLANE_CTL_ROTATE_180;
+		plane_ctl_rotation = PLANE_CTL_ROTATE_180;
 		break;
-
 	case BIT(DRM_ROTATE_270):
-		plane_ctl |= PLANE_CTL_ROTATE_270;
+		plane_ctl_rotation = PLANE_CTL_ROTATE_270;
 		break;
+	default:
+		MISSING_CASE(rotation);
 	}
 
+	return plane_ctl_rotation;
+}
+
+static void skylake_update_primary_plane(struct drm_crtc *crtc,
+					 struct drm_framebuffer *fb,
+					 int x, int y)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_i915_gem_object *obj;
+	int pipe = intel_crtc->pipe;
+	u32 plane_ctl, stride_div, stride;
+	u32 tile_height, plane_offset, plane_size;
+	unsigned int rotation;
+	int x_offset, y_offset;
+	unsigned long surf_addr;
+	struct drm_plane *plane;
+	struct intel_crtc_state *crtc_state = intel_crtc->config;
+	struct intel_plane_state *plane_state;
+	int src_x = 0, src_y = 0, src_w = 0, src_h = 0;
+	int dst_x = 0, dst_y = 0, dst_w = 0, dst_h = 0;
+	int scaler_id = -1;
+
+	plane = crtc->primary;
+	plane_state = plane ? to_intel_plane_state(crtc->primary->state) : NULL;
+
+	if (!intel_crtc->primary_enabled) {
+		I915_WRITE(PLANE_CTL(pipe, 0), 0);
+		I915_WRITE(PLANE_SURF(pipe, 0), 0);
+		POSTING_READ(PLANE_CTL(pipe, 0));
+		return;
+	}
+
+	plane_ctl = PLANE_CTL_ENABLE |
+		    PLANE_CTL_PIPE_GAMMA_ENABLE |
+		    PLANE_CTL_PIPE_CSC_ENABLE;
+
+	plane_ctl |= skl_plane_ctl_format(fb->pixel_format);
+	plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]);
+	plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
+
+	rotation = plane->state->rotation;
+	plane_ctl |= skl_plane_ctl_rotation(rotation);
+
 	obj = intel_fb_obj(fb);
 	stride_div = intel_fb_stride_alignment(dev, fb->modifier[0],
 					       fb->pixel_format);
 	surf_addr = intel_plane_obj_offset(to_intel_plane(plane), obj);
 
+	if (plane_state && drm_rect_width(&plane_state->src)) {
+		scaler_id = plane_state->scaler_id;
+		src_x = plane_state->src.x1 >> 16;
+		src_y = plane_state->src.y1 >> 16;
+		src_w = drm_rect_width(&plane_state->src) >> 16;
+		src_h = drm_rect_height(&plane_state->src) >> 16;
+		dst_x = plane_state->dst.x1;
+		dst_y = plane_state->dst.y1;
+		dst_w = drm_rect_width(&plane_state->dst);
+		dst_h = drm_rect_height(&plane_state->dst);
+
+		WARN_ON(x != src_x || y != src_y);
+	} else {
+		src_w = intel_crtc->config->pipe_src_w;
+		src_h = intel_crtc->config->pipe_src_h;
+	}
+
 	if (intel_rotation_90_or_270(rotation)) {
 		/* stride = Surface height in tiles */
 		tile_height = intel_tile_height(dev, fb->bits_per_pixel,
 						fb->modifier[0]);
 		stride = DIV_ROUND_UP(fb->height, tile_height);
-		x_offset = stride * tile_height - y - (plane->state->src_h >> 16);
+		x_offset = stride * tile_height - y - src_h;
 		y_offset = x;
-		plane_size = ((plane->state->src_w >> 16) - 1) << 16 |
-					((plane->state->src_h >> 16) - 1);
+		plane_size = (src_w - 1) << 16 | (src_h - 1);
 	} else {
 		stride = fb->pitches[0] / stride_div;
 		x_offset = x;
 		y_offset = y;
-		plane_size = ((plane->state->src_h >> 16) - 1) << 16 |
-			((plane->state->src_w >> 16) - 1);
+		plane_size = (src_h - 1) << 16 | (src_w - 1);
 	}
 	plane_offset = y_offset << 16 | x_offset;
 
 	I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
-	I915_WRITE(PLANE_POS(pipe, 0), 0);
 	I915_WRITE(PLANE_OFFSET(pipe, 0), plane_offset);
 	I915_WRITE(PLANE_SIZE(pipe, 0), plane_size);
 	I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
+
+	if (scaler_id >= 0) {
+		uint32_t ps_ctrl = 0;
+
+		WARN_ON(!dst_w || !dst_h);
+		ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(0) |
+			crtc_state->scaler_state.scalers[scaler_id].mode;
+		I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
+		I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
+		I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (dst_x << 16) | dst_y);
+		I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id), (dst_w << 16) | dst_h);
+		I915_WRITE(PLANE_POS(pipe, 0), 0);
+	} else {
+		I915_WRITE(PLANE_POS(pipe, 0), (dst_y << 16) | dst_x);
+	}
+
 	I915_WRITE(PLANE_SURF(pipe, 0), surf_addr);
 
 	POSTING_READ(PLANE_SURF(pipe, 0));
@@ -4338,6 +4411,7 @@ skl_update_scaler_users(
 	int *scaler_id;
 	struct drm_framebuffer *fb;
 	struct intel_crtc_scaler_state *scaler_state;
+	unsigned int rotation;
 
 	if (!intel_crtc || !crtc_state)
 		return 0;
@@ -4353,6 +4427,7 @@ skl_update_scaler_users(
 		dst_w = drm_rect_width(&plane_state->dst);
 		dst_h = drm_rect_height(&plane_state->dst);
 		scaler_id = &plane_state->scaler_id;
+		rotation = plane_state->base.rotation;
 	} else {
 		struct drm_display_mode *adjusted_mode =
 			&crtc_state->base.adjusted_mode;
@@ -4361,8 +4436,12 @@ skl_update_scaler_users(
 		dst_w = adjusted_mode->hdisplay;
 		dst_h = adjusted_mode->vdisplay;
 		scaler_id = &scaler_state->scaler_id;
+		rotation = DRM_ROTATE_0;
 	}
-	need_scaling = (src_w != dst_w || src_h != dst_h);
+
+	need_scaling = intel_rotation_90_or_270(rotation) ?
+		(src_h != dst_w || src_w != dst_h):
+		(src_w != dst_w || src_h != dst_h);
 
 	/*
 	 * if plane is being disabled or scaler is no more required or force detach
@@ -12805,6 +12884,36 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
 	}
 }
 
+int
+skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state)
+{
+	int max_scale;
+	struct drm_device *dev;
+	struct drm_i915_private *dev_priv;
+	int crtc_clock, cdclk;
+
+	if (!intel_crtc || !crtc_state)
+		return DRM_PLANE_HELPER_NO_SCALING;
+
+	dev = intel_crtc->base.dev;
+	dev_priv = dev->dev_private;
+	crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
+	cdclk = dev_priv->display.get_display_clock_speed(dev);
+
+	if (!crtc_clock || !cdclk)
+		return DRM_PLANE_HELPER_NO_SCALING;
+
+	/*
+	 * skl max scale is lower of:
+	 *    close to 3 but not 3, -1 is for that purpose
+	 *            or
+	 *    cdclk/crtc_clock
+	 */
+	max_scale = min((1 << 16) * 3 - 1, (1 << 8) * ((cdclk << 8) / crtc_clock));
+
+	return max_scale;
+}
+
 static int
 intel_check_primary_plane(struct drm_plane *plane,
 			  struct intel_plane_state *state)
@@ -12813,23 +12922,31 @@ intel_check_primary_plane(struct drm_plane *plane,
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_crtc *crtc = state->base.crtc;
 	struct intel_crtc *intel_crtc;
+	struct intel_crtc_state *crtc_state;
 	struct drm_framebuffer *fb = state->base.fb;
 	struct drm_rect *dest = &state->dst;
 	struct drm_rect *src = &state->src;
 	const struct drm_rect *clip = &state->clip;
 	bool can_position = false;
+	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
+	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
 	int ret;
 
 	crtc = crtc ? crtc : plane->crtc;
 	intel_crtc = to_intel_crtc(crtc);
+	crtc_state = state->base.state ?
+		intel_atomic_get_crtc_state(state->base.state, intel_crtc) : NULL;
 
-	if (INTEL_INFO(dev)->gen >= 9)
+	if (INTEL_INFO(dev)->gen >= 9) {
+		min_scale = 1;
+		max_scale = skl_max_scale(intel_crtc, crtc_state);
 		can_position = true;
+	}
 
 	ret = drm_plane_helper_check_update(plane, crtc, fb,
 					    src, dest, clip,
-					    DRM_PLANE_HELPER_NO_SCALING,
-					    DRM_PLANE_HELPER_NO_SCALING,
+					    min_scale,
+					    max_scale,
 					    can_position, true,
 					    &state->visible);
 	if (ret)
@@ -12874,6 +12991,13 @@ intel_check_primary_plane(struct drm_plane *plane,
 			intel_crtc->atomic.update_wm = true;
 	}
 
+	if (INTEL_INFO(dev)->gen >= 9) {
+		ret = skl_update_scaler_users(intel_crtc, crtc_state,
+			to_intel_plane(plane), state, 0);
+		if (ret)
+			return ret;
+	}
+
 	return 0;
 }
 
@@ -13053,6 +13177,9 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
 
 	primary->can_scale = false;
 	primary->max_downscale = 1;
+	if (INTEL_INFO(dev)->gen >= 9) {
+		primary->can_scale = true;
+	}
 	state->scaler_id = -1;
 	primary->pipe = pipe;
 	primary->plane = pipe;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 275a4ef..c9bc975 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -288,11 +288,11 @@ struct intel_initial_plane_config {
 #define SKL_MIN_SRC_W 8
 #define SKL_MAX_SRC_W 4096
 #define SKL_MIN_SRC_H 8
-#define SKL_MAX_SRC_H 2304
+#define SKL_MAX_SRC_H 4096
 #define SKL_MIN_DST_W 8
 #define SKL_MAX_DST_W 4096
 #define SKL_MIN_DST_H 8
-#define SKL_MAX_DST_H 2304
+#define SKL_MAX_DST_H 4096
 
 struct intel_scaler {
 	int id;
@@ -1131,9 +1131,13 @@ void skl_detach_scalers(struct intel_crtc *intel_crtc);
 int skl_update_scaler_users(struct intel_crtc *intel_crtc,
 	struct intel_crtc_state *crtc_state, struct intel_plane *intel_plane,
 	struct intel_plane_state *plane_state, int force_detach);
+int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state);
 
 unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
 				     struct drm_i915_gem_object *obj);
+u32 skl_plane_ctl_format(uint32_t pixel_format);
+u32 skl_plane_ctl_tiling(uint64_t fb_modifier);
+u32 skl_plane_ctl_rotation(unsigned int rotation);
 
 /* intel_dp.c */
 void intel_dp_init(struct drm_device *dev, int output_reg, enum port port);
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 0cb3767..2f42777 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -1150,6 +1150,15 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
 	}
 
 	intel_plane = to_intel_plane(plane);
+
+	if (INTEL_INFO(dev)->gen >= 9) {
+		/* plane scaling and colorkey are mutually exclusive */
+		if (to_intel_plane_state(plane->state)->scaler_id >= 0) {
+			DRM_ERROR("colorkey not allowed with scaler\n");
+			return -EINVAL;
+		}
+	}
+
 	intel_plane->ckey = *set;
 
 	/*
-- 
1.7.9.5

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

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

* [PATCH 14/14] drm/i915: skylake sprite plane scaling using shared scalers
  2015-04-07 22:28 ` [PATCH 14/14] drm/i915: skylake sprite " Chandra Konduru
  2015-04-09 23:43   ` Chandra Konduru
@ 2015-04-15 22:15   ` Chandra Konduru
  2015-04-16  7:42     ` Daniel Vetter
  2015-04-16  8:18     ` Jindal, Sonika
  1 sibling, 2 replies; 54+ messages in thread
From: Chandra Konduru @ 2015-04-15 22:15 UTC (permalink / raw)
  To: intel-gfx; +Cc: daniel.vetter, ander.conselvan.de.oliveira

This patch enables skylake sprite plane display scaling using shared
scalers atomic desgin.

v2:
-use single copy of scaler limits (Matt)

v3:
-detaching scalers moved to crtc commit path (Matt)

v4:
-changes to align with updated scaler structures (Matt, me)
-keep sprite src rect in 16.16 format (Matt, Daniel)

v5:
-rebased on top of 90/270 rotation changes (me)
-Refactored skl_update_plane to reduce its size (Daniel)
 It is a step towards having a single function covering all planes.

Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Testcase: kms_plane_scaling
---
 drivers/gpu/drm/i915/intel_sprite.c |  125 ++++++++++++++---------------------
 1 file changed, 48 insertions(+), 77 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 2f42777..497bc1d 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -33,6 +33,7 @@
 #include <drm/drm_crtc.h>
 #include <drm/drm_fourcc.h>
 #include <drm/drm_rect.h>
+#include <drm/drm_atomic.h>
 #include <drm/drm_plane_helper.h>
 #include "intel_drv.h"
 #include <drm/i915_drm.h>
@@ -197,80 +198,17 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
 	u32 tile_height, plane_offset, plane_size;
 	unsigned int rotation;
 	int x_offset, y_offset;
+	struct intel_crtc_state *crtc_state = to_intel_crtc(crtc)->config;
+	int scaler_id;
 
 	plane_ctl = PLANE_CTL_ENABLE |
 		PLANE_CTL_PIPE_CSC_ENABLE;
 
-	switch (fb->pixel_format) {
-	case DRM_FORMAT_RGB565:
-		plane_ctl |= PLANE_CTL_FORMAT_RGB_565;
-		break;
-	case DRM_FORMAT_XBGR8888:
-		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
-		break;
-	case DRM_FORMAT_XRGB8888:
-		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
-		break;
-	/*
-	 * XXX: For ARBG/ABGR formats we default to expecting scanout buffers
-	 * to be already pre-multiplied. We need to add a knob (or a different
-	 * DRM_FORMAT) for user-space to configure that.
-	 */
-	case DRM_FORMAT_ABGR8888:
-		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 |
-			     PLANE_CTL_ORDER_RGBX |
-			     PLANE_CTL_ALPHA_SW_PREMULTIPLY;
-		break;
-	case DRM_FORMAT_ARGB8888:
-		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 |
-			     PLANE_CTL_ALPHA_SW_PREMULTIPLY;
-		break;
-	case DRM_FORMAT_YUYV:
-		plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV;
-		break;
-	case DRM_FORMAT_YVYU:
-		plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU;
-		break;
-	case DRM_FORMAT_UYVY:
-		plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY;
-		break;
-	case DRM_FORMAT_VYUY:
-		plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
-		break;
-	default:
-		BUG();
-	}
-
-	switch (fb->modifier[0]) {
-	case DRM_FORMAT_MOD_NONE:
-		break;
-	case I915_FORMAT_MOD_X_TILED:
-		plane_ctl |= PLANE_CTL_TILED_X;
-		break;
-	case I915_FORMAT_MOD_Y_TILED:
-		plane_ctl |= PLANE_CTL_TILED_Y;
-		break;
-	case I915_FORMAT_MOD_Yf_TILED:
-		plane_ctl |= PLANE_CTL_TILED_YF;
-		break;
-	default:
-		MISSING_CASE(fb->modifier[0]);
-	}
+	plane_ctl |= skl_plane_ctl_format(fb->pixel_format);
+	plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]);
 
 	rotation = drm_plane->state->rotation;
-	switch (rotation) {
-	case BIT(DRM_ROTATE_90):
-		plane_ctl |= PLANE_CTL_ROTATE_90;
-		break;
-
-	case BIT(DRM_ROTATE_180):
-		plane_ctl |= PLANE_CTL_ROTATE_180;
-		break;
-
-	case BIT(DRM_ROTATE_270):
-		plane_ctl |= PLANE_CTL_ROTATE_270;
-		break;
-	}
+	plane_ctl |= skl_plane_ctl_rotation(rotation);
 
 	intel_update_sprite_watermarks(drm_plane, crtc, src_w, src_h,
 				       pixel_size, true,
@@ -279,6 +217,8 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
 	stride_div = intel_fb_stride_alignment(dev, fb->modifier[0],
 					       fb->pixel_format);
 
+	scaler_id = to_intel_plane_state(drm_plane->state)->scaler_id;
+
 	/* Sizes are 0 based */
 	src_w--;
 	src_h--;
@@ -316,8 +256,27 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
 
 	I915_WRITE(PLANE_OFFSET(pipe, plane), plane_offset);
 	I915_WRITE(PLANE_STRIDE(pipe, plane), stride);
-	I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x);
 	I915_WRITE(PLANE_SIZE(pipe, plane), plane_size);
+
+	/* program plane scaler */
+	if (scaler_id >= 0) {
+		uint32_t ps_ctrl = 0;
+
+		DRM_DEBUG_KMS("plane = %d PS_PLANE_SEL(plane) = 0x%x\n", plane,
+			PS_PLANE_SEL(plane));
+		ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(plane) |
+			crtc_state->scaler_state.scalers[scaler_id].mode;
+		I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
+		I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
+		I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
+		I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id),
+			((crtc_w + 1) << 16)|(crtc_h + 1));
+
+		I915_WRITE(PLANE_POS(pipe, plane), 0);
+	} else {
+		I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x);
+	}
+
 	I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl);
 	I915_WRITE(PLANE_SURF(pipe, plane), surf_addr);
 	POSTING_READ(PLANE_SURF(pipe, plane));
@@ -894,7 +853,9 @@ static int
 intel_check_sprite_plane(struct drm_plane *plane,
 			 struct intel_plane_state *state)
 {
+	struct drm_device *dev = plane->dev;
 	struct intel_crtc *intel_crtc = to_intel_crtc(state->base.crtc);
+	struct intel_crtc_state *crtc_state;
 	struct intel_plane *intel_plane = to_intel_plane(plane);
 	struct drm_framebuffer *fb = state->base.fb;
 	int crtc_x, crtc_y;
@@ -906,8 +867,11 @@ intel_check_sprite_plane(struct drm_plane *plane,
 	int hscale, vscale;
 	int max_scale, min_scale;
 	int pixel_size;
+	int ret;
 
 	intel_crtc = intel_crtc ? intel_crtc : to_intel_crtc(plane->crtc);
+	crtc_state = state->base.state ?
+		intel_atomic_get_crtc_state(state->base.state, intel_crtc) : NULL;
 
 	if (!fb) {
 		state->visible = false;
@@ -934,6 +898,11 @@ intel_check_sprite_plane(struct drm_plane *plane,
 	max_scale = intel_plane->max_downscale << 16;
 	min_scale = intel_plane->can_scale ? 1 : (1 << 16);
 
+	if (INTEL_INFO(dev)->gen >= 9) {
+		min_scale = 1;
+		max_scale = skl_max_scale(intel_crtc, crtc_state);
+	}
+
 	drm_rect_rotate(src, fb->width << 16, fb->height << 16,
 			state->base.rotation);
 
@@ -1029,8 +998,8 @@ intel_check_sprite_plane(struct drm_plane *plane,
 		width_bytes = ((src_x * pixel_size) & 63) +
 					src_w * pixel_size;
 
-		if (src_w > 2048 || src_h > 2048 ||
-		    width_bytes > 4096 || fb->pitches[0] > 4096) {
+		if (INTEL_INFO(dev)->gen < 9 && (src_w > 2048 || src_h > 2048 ||
+		    width_bytes > 4096 || fb->pitches[0] > 4096)) {
 			DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
 			return -EINVAL;
 		}
@@ -1084,6 +1053,13 @@ finish:
 		}
 	}
 
+	if (INTEL_INFO(dev)->gen >= 9) {
+		ret = skl_update_scaler_users(intel_crtc, crtc_state, intel_plane,
+			state, 0);
+		if (ret)
+			return ret;
+	}
+
 	return 0;
 }
 
@@ -1295,12 +1271,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
 		}
 		break;
 	case 9:
-		/*
-		 * FIXME: Skylake planes can be scaled (with some restrictions),
-		 * but this is for another time.
-		 */
-		intel_plane->can_scale = false;
-		intel_plane->max_downscale = 1;
+		intel_plane->can_scale = true;
 		intel_plane->update_plane = skl_update_plane;
 		intel_plane->disable_plane = skl_disable_plane;
 		state->scaler_id = -1;
-- 
1.7.9.5

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

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

* Re: [PATCH 13/14] drm/i915: skylake primary plane scaling using shared scalers
  2015-04-15 22:14   ` Chandra Konduru
@ 2015-04-15 23:08     ` Konduru, Chandra
  2015-04-16  7:36     ` Daniel Vetter
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 54+ messages in thread
From: Konduru, Chandra @ 2015-04-15 23:08 UTC (permalink / raw)
  To: intel-gfx, Vetter, Daniel, Jindal, Sonika; +Cc: Conselvan De Oliveira, Ander

Sonika,
I have rebased 13/14 and 14/14 of scaler series on top of 90/270
and did some refactoring to reduce function size. 
Previous versions are already reviewed and Matt gave r-b
for those changes.
Can you review v5 changes and give r-b or ack for them?
You can see below (v5) list of changes triggered by 90/270.


-Chandra

> -----Original Message-----
> From: Konduru, Chandra
> Sent: Wednesday, April 15, 2015 3:15 PM
> To: intel-gfx@lists.freedesktop.org
> Cc: Konduru, Chandra; Jindal, Sonika; Roper, Matthew D; Vetter, Daniel;
> Conselvan De Oliveira, Ander
> Subject: [PATCH 13/14] drm/i915: skylake primary plane scaling using shared
> scalers
> 
> This patch enables skylake primary plane scaling using shared
> scalers atomic desgin.
> 
> v2:
> -use single copy of scaler limits (Matt)
> 
> v3:
> -move detach_scalers to crtc commit path (Matt)
> -use values in plane_state->src as regular integers (me)
> 
> v4:
> -changes to align with updated scaler structures (Matt, me)
> -keep plane src rect in 16.16 format (Matt, Daniel)
> 
> v5:
> -Rebased on top of 90/270 rotation changes (me)
> -Fixed an issue introduced by 90/270 changes where plane programming
>  is using drm_plane->state rect instead of intel_plane->state rect.
>  This change also required for scaling to work properly. (me)
> -With 90/270, updated limits to cover both portrait and landscape usages (me)
> -Refactored skylake_update_primary_plane to reduce its size (Daniel)
>  Added helper functions for refactoring are comprehended enough to be
>  used for skylake_update_plane (for sprite) too. One stop towards
>  having single function for all planes.
> 
> Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
> Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
> Testcase: kms_plane_scaling
> ---
>  drivers/gpu/drm/i915/intel_atomic.c  |    5 +-
>  drivers/gpu/drm/i915/intel_display.c |  261 +++++++++++++++++++++++++------
> ---
>  drivers/gpu/drm/i915/intel_drv.h     |    8 +-
>  drivers/gpu/drm/i915/intel_sprite.c  |    9 ++
>  4 files changed, 213 insertions(+), 70 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_atomic.c
> b/drivers/gpu/drm/i915/intel_atomic.c
> index 3c4b7cd..cb6d5f2 100644
> --- a/drivers/gpu/drm/i915/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> @@ -169,7 +169,7 @@ int intel_atomic_commit(struct drm_device *dev,
>  		plane->state->state = NULL;
>  	}
> 
> -	/* swap crtc_state */
> +	/* swap crtc_scaler_state */
>  	for (i = 0; i < dev->mode_config.num_crtc; i++) {
>  		struct drm_crtc *crtc = state->crtcs[i];
>  		if (!crtc) {
> @@ -178,6 +178,9 @@ int intel_atomic_commit(struct drm_device *dev,
> 
>  		to_intel_crtc(crtc)->config->scaler_state =
>  			to_intel_crtc_state(state->crtc_states[i])->scaler_state;
> +
> +		if (INTEL_INFO(dev)->gen >= 9)
> +			skl_detach_scalers(to_intel_crtc(crtc));
>  	}
> 
>  	drm_atomic_helper_commit_planes(dev, state);
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index 5f7a40f..7f3ae8e 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2960,126 +2960,199 @@ void skl_detach_scalers(struct intel_crtc
> *intel_crtc)
>  	}
>  }
> 
> -static void skylake_update_primary_plane(struct drm_crtc *crtc,
> -					 struct drm_framebuffer *fb,
> -					 int x, int y)
> +u32 skl_plane_ctl_format(uint32_t pixel_format)
>  {
> -	struct drm_device *dev = crtc->dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -	struct drm_i915_gem_object *obj;
> -	int pipe = intel_crtc->pipe;
> -	u32 plane_ctl, stride_div, stride;
> -	u32 tile_height, plane_offset, plane_size;
> -	unsigned int rotation;
> -	int x_offset, y_offset;
> -	unsigned long surf_addr;
> -	struct drm_plane *plane;
> -
> -	if (!intel_crtc->primary_enabled) {
> -		I915_WRITE(PLANE_CTL(pipe, 0), 0);
> -		I915_WRITE(PLANE_SURF(pipe, 0), 0);
> -		POSTING_READ(PLANE_CTL(pipe, 0));
> -		return;
> -	}
> -
> -	plane_ctl = PLANE_CTL_ENABLE |
> -		    PLANE_CTL_PIPE_GAMMA_ENABLE |
> -		    PLANE_CTL_PIPE_CSC_ENABLE;
> -
> -	switch (fb->pixel_format) {
> +	u32 plane_ctl_format = 0;
> +	switch (pixel_format) {
>  	case DRM_FORMAT_RGB565:
> -		plane_ctl |= PLANE_CTL_FORMAT_RGB_565;
> -		break;
> -	case DRM_FORMAT_XRGB8888:
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> -		break;
> -	case DRM_FORMAT_ARGB8888:
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> -		plane_ctl |= PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> +		plane_ctl_format = PLANE_CTL_FORMAT_RGB_565;
>  		break;
>  	case DRM_FORMAT_XBGR8888:
> -		plane_ctl |= PLANE_CTL_ORDER_RGBX;
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 |
> PLANE_CTL_ORDER_RGBX;
>  		break;
> +	case DRM_FORMAT_XRGB8888:
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888;
> +		break;
> +	/*
> +	 * XXX: For ARBG/ABGR formats we default to expecting scanout buffers
> +	 * to be already pre-multiplied. We need to add a knob (or a different
> +	 * DRM_FORMAT) for user-space to configure that.
> +	 */
>  	case DRM_FORMAT_ABGR8888:
> -		plane_ctl |= PLANE_CTL_ORDER_RGBX;
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> -		plane_ctl |= PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 |
> PLANE_CTL_ORDER_RGBX |
> +			PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> +		break;
> +	case DRM_FORMAT_ARGB8888:
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 |
> +			PLANE_CTL_ALPHA_SW_PREMULTIPLY;
>  		break;
>  	case DRM_FORMAT_XRGB2101010:
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010;
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_2101010;
>  		break;
>  	case DRM_FORMAT_XBGR2101010:
> -		plane_ctl |= PLANE_CTL_ORDER_RGBX;
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010;
> +		plane_ctl_format = PLANE_CTL_ORDER_RGBX |
> PLANE_CTL_FORMAT_XRGB_2101010;
> +		break;
> +	case DRM_FORMAT_YUYV:
> +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 |
> PLANE_CTL_YUV422_YUYV;
> +		break;
> +	case DRM_FORMAT_YVYU:
> +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 |
> PLANE_CTL_YUV422_YVYU;
> +		break;
> +	case DRM_FORMAT_UYVY:
> +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 |
> PLANE_CTL_YUV422_UYVY;
> +		break;
> +	case DRM_FORMAT_VYUY:
> +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 |
> PLANE_CTL_YUV422_VYUY;
>  		break;
>  	default:
>  		BUG();
>  	}
> +	return plane_ctl_format;
> +}
> 
> -	switch (fb->modifier[0]) {
> +u32 skl_plane_ctl_tiling(uint64_t fb_modifier)
> +{
> +	u32 plane_ctl_tiling = 0;
> +	switch (fb_modifier) {
>  	case DRM_FORMAT_MOD_NONE:
>  		break;
>  	case I915_FORMAT_MOD_X_TILED:
> -		plane_ctl |= PLANE_CTL_TILED_X;
> +		plane_ctl_tiling = PLANE_CTL_TILED_X;
>  		break;
>  	case I915_FORMAT_MOD_Y_TILED:
> -		plane_ctl |= PLANE_CTL_TILED_Y;
> +		plane_ctl_tiling = PLANE_CTL_TILED_Y;
>  		break;
>  	case I915_FORMAT_MOD_Yf_TILED:
> -		plane_ctl |= PLANE_CTL_TILED_YF;
> +		plane_ctl_tiling = PLANE_CTL_TILED_YF;
>  		break;
>  	default:
> -		MISSING_CASE(fb->modifier[0]);
> +		MISSING_CASE(fb_modifier);
>  	}
> +	return plane_ctl_tiling;
> +}
> 
> -	plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
> -
> -	plane = crtc->primary;
> -	rotation = plane->state->rotation;
> +u32 skl_plane_ctl_rotation(unsigned int rotation)
> +{
> +	u32 plane_ctl_rotation = 0;
>  	switch (rotation) {
> +	case BIT(DRM_ROTATE_0):
> +		break;
>  	case BIT(DRM_ROTATE_90):
> -		plane_ctl |= PLANE_CTL_ROTATE_90;
> +		plane_ctl_rotation = PLANE_CTL_ROTATE_90;
>  		break;
> -
>  	case BIT(DRM_ROTATE_180):
> -		plane_ctl |= PLANE_CTL_ROTATE_180;
> +		plane_ctl_rotation = PLANE_CTL_ROTATE_180;
>  		break;
> -
>  	case BIT(DRM_ROTATE_270):
> -		plane_ctl |= PLANE_CTL_ROTATE_270;
> +		plane_ctl_rotation = PLANE_CTL_ROTATE_270;
>  		break;
> +	default:
> +		MISSING_CASE(rotation);
>  	}
> 
> +	return plane_ctl_rotation;
> +}
> +
> +static void skylake_update_primary_plane(struct drm_crtc *crtc,
> +					 struct drm_framebuffer *fb,
> +					 int x, int y)
> +{
> +	struct drm_device *dev = crtc->dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct drm_i915_gem_object *obj;
> +	int pipe = intel_crtc->pipe;
> +	u32 plane_ctl, stride_div, stride;
> +	u32 tile_height, plane_offset, plane_size;
> +	unsigned int rotation;
> +	int x_offset, y_offset;
> +	unsigned long surf_addr;
> +	struct drm_plane *plane;
> +	struct intel_crtc_state *crtc_state = intel_crtc->config;
> +	struct intel_plane_state *plane_state;
> +	int src_x = 0, src_y = 0, src_w = 0, src_h = 0;
> +	int dst_x = 0, dst_y = 0, dst_w = 0, dst_h = 0;
> +	int scaler_id = -1;
> +
> +	plane = crtc->primary;
> +	plane_state = plane ? to_intel_plane_state(crtc->primary->state) :
> NULL;
> +
> +	if (!intel_crtc->primary_enabled) {
> +		I915_WRITE(PLANE_CTL(pipe, 0), 0);
> +		I915_WRITE(PLANE_SURF(pipe, 0), 0);
> +		POSTING_READ(PLANE_CTL(pipe, 0));
> +		return;
> +	}
> +
> +	plane_ctl = PLANE_CTL_ENABLE |
> +		    PLANE_CTL_PIPE_GAMMA_ENABLE |
> +		    PLANE_CTL_PIPE_CSC_ENABLE;
> +
> +	plane_ctl |= skl_plane_ctl_format(fb->pixel_format);
> +	plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]);
> +	plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
> +
> +	rotation = plane->state->rotation;
> +	plane_ctl |= skl_plane_ctl_rotation(rotation);
> +
>  	obj = intel_fb_obj(fb);
>  	stride_div = intel_fb_stride_alignment(dev, fb->modifier[0],
>  					       fb->pixel_format);
>  	surf_addr = intel_plane_obj_offset(to_intel_plane(plane), obj);
> 
> +	if (plane_state && drm_rect_width(&plane_state->src)) {
> +		scaler_id = plane_state->scaler_id;
> +		src_x = plane_state->src.x1 >> 16;
> +		src_y = plane_state->src.y1 >> 16;
> +		src_w = drm_rect_width(&plane_state->src) >> 16;
> +		src_h = drm_rect_height(&plane_state->src) >> 16;
> +		dst_x = plane_state->dst.x1;
> +		dst_y = plane_state->dst.y1;
> +		dst_w = drm_rect_width(&plane_state->dst);
> +		dst_h = drm_rect_height(&plane_state->dst);
> +
> +		WARN_ON(x != src_x || y != src_y);
> +	} else {
> +		src_w = intel_crtc->config->pipe_src_w;
> +		src_h = intel_crtc->config->pipe_src_h;
> +	}
> +
>  	if (intel_rotation_90_or_270(rotation)) {
>  		/* stride = Surface height in tiles */
>  		tile_height = intel_tile_height(dev, fb->bits_per_pixel,
>  						fb->modifier[0]);
>  		stride = DIV_ROUND_UP(fb->height, tile_height);
> -		x_offset = stride * tile_height - y - (plane->state->src_h >> 16);
> +		x_offset = stride * tile_height - y - src_h;
>  		y_offset = x;
> -		plane_size = ((plane->state->src_w >> 16) - 1) << 16 |
> -					((plane->state->src_h >> 16) - 1);
> +		plane_size = (src_w - 1) << 16 | (src_h - 1);
>  	} else {
>  		stride = fb->pitches[0] / stride_div;
>  		x_offset = x;
>  		y_offset = y;
> -		plane_size = ((plane->state->src_h >> 16) - 1) << 16 |
> -			((plane->state->src_w >> 16) - 1);
> +		plane_size = (src_h - 1) << 16 | (src_w - 1);
>  	}
>  	plane_offset = y_offset << 16 | x_offset;
> 
>  	I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
> -	I915_WRITE(PLANE_POS(pipe, 0), 0);
>  	I915_WRITE(PLANE_OFFSET(pipe, 0), plane_offset);
>  	I915_WRITE(PLANE_SIZE(pipe, 0), plane_size);
>  	I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
> +
> +	if (scaler_id >= 0) {
> +		uint32_t ps_ctrl = 0;
> +
> +		WARN_ON(!dst_w || !dst_h);
> +		ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(0) |
> +			crtc_state->scaler_state.scalers[scaler_id].mode;
> +		I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
> +		I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
> +		I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (dst_x << 16) |
> dst_y);
> +		I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id), (dst_w << 16) |
> dst_h);
> +		I915_WRITE(PLANE_POS(pipe, 0), 0);
> +	} else {
> +		I915_WRITE(PLANE_POS(pipe, 0), (dst_y << 16) | dst_x);
> +	}
> +
>  	I915_WRITE(PLANE_SURF(pipe, 0), surf_addr);
> 
>  	POSTING_READ(PLANE_SURF(pipe, 0));
> @@ -4338,6 +4411,7 @@ skl_update_scaler_users(
>  	int *scaler_id;
>  	struct drm_framebuffer *fb;
>  	struct intel_crtc_scaler_state *scaler_state;
> +	unsigned int rotation;
> 
>  	if (!intel_crtc || !crtc_state)
>  		return 0;
> @@ -4353,6 +4427,7 @@ skl_update_scaler_users(
>  		dst_w = drm_rect_width(&plane_state->dst);
>  		dst_h = drm_rect_height(&plane_state->dst);
>  		scaler_id = &plane_state->scaler_id;
> +		rotation = plane_state->base.rotation;
>  	} else {
>  		struct drm_display_mode *adjusted_mode =
>  			&crtc_state->base.adjusted_mode;
> @@ -4361,8 +4436,12 @@ skl_update_scaler_users(
>  		dst_w = adjusted_mode->hdisplay;
>  		dst_h = adjusted_mode->vdisplay;
>  		scaler_id = &scaler_state->scaler_id;
> +		rotation = DRM_ROTATE_0;
>  	}
> -	need_scaling = (src_w != dst_w || src_h != dst_h);
> +
> +	need_scaling = intel_rotation_90_or_270(rotation) ?
> +		(src_h != dst_w || src_w != dst_h):
> +		(src_w != dst_w || src_h != dst_h);
> 
>  	/*
>  	 * if plane is being disabled or scaler is no more required or force detach
> @@ -12805,6 +12884,36 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
>  	}
>  }
> 
> +int
> +skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state)
> +{
> +	int max_scale;
> +	struct drm_device *dev;
> +	struct drm_i915_private *dev_priv;
> +	int crtc_clock, cdclk;
> +
> +	if (!intel_crtc || !crtc_state)
> +		return DRM_PLANE_HELPER_NO_SCALING;
> +
> +	dev = intel_crtc->base.dev;
> +	dev_priv = dev->dev_private;
> +	crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
> +	cdclk = dev_priv->display.get_display_clock_speed(dev);
> +
> +	if (!crtc_clock || !cdclk)
> +		return DRM_PLANE_HELPER_NO_SCALING;
> +
> +	/*
> +	 * skl max scale is lower of:
> +	 *    close to 3 but not 3, -1 is for that purpose
> +	 *            or
> +	 *    cdclk/crtc_clock
> +	 */
> +	max_scale = min((1 << 16) * 3 - 1, (1 << 8) * ((cdclk << 8) / crtc_clock));
> +
> +	return max_scale;
> +}
> +
>  static int
>  intel_check_primary_plane(struct drm_plane *plane,
>  			  struct intel_plane_state *state)
> @@ -12813,23 +12922,31 @@ intel_check_primary_plane(struct drm_plane
> *plane,
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct drm_crtc *crtc = state->base.crtc;
>  	struct intel_crtc *intel_crtc;
> +	struct intel_crtc_state *crtc_state;
>  	struct drm_framebuffer *fb = state->base.fb;
>  	struct drm_rect *dest = &state->dst;
>  	struct drm_rect *src = &state->src;
>  	const struct drm_rect *clip = &state->clip;
>  	bool can_position = false;
> +	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
> +	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
>  	int ret;
> 
>  	crtc = crtc ? crtc : plane->crtc;
>  	intel_crtc = to_intel_crtc(crtc);
> +	crtc_state = state->base.state ?
> +		intel_atomic_get_crtc_state(state->base.state, intel_crtc) :
> NULL;
> 
> -	if (INTEL_INFO(dev)->gen >= 9)
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		min_scale = 1;
> +		max_scale = skl_max_scale(intel_crtc, crtc_state);
>  		can_position = true;
> +	}
> 
>  	ret = drm_plane_helper_check_update(plane, crtc, fb,
>  					    src, dest, clip,
> -					    DRM_PLANE_HELPER_NO_SCALING,
> -					    DRM_PLANE_HELPER_NO_SCALING,
> +					    min_scale,
> +					    max_scale,
>  					    can_position, true,
>  					    &state->visible);
>  	if (ret)
> @@ -12874,6 +12991,13 @@ intel_check_primary_plane(struct drm_plane
> *plane,
>  			intel_crtc->atomic.update_wm = true;
>  	}
> 
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		ret = skl_update_scaler_users(intel_crtc, crtc_state,
> +			to_intel_plane(plane), state, 0);
> +		if (ret)
> +			return ret;
> +	}
> +
>  	return 0;
>  }
> 
> @@ -13053,6 +13177,9 @@ static struct drm_plane
> *intel_primary_plane_create(struct drm_device *dev,
> 
>  	primary->can_scale = false;
>  	primary->max_downscale = 1;
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		primary->can_scale = true;
> +	}
>  	state->scaler_id = -1;
>  	primary->pipe = pipe;
>  	primary->plane = pipe;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 275a4ef..c9bc975 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -288,11 +288,11 @@ struct intel_initial_plane_config {
>  #define SKL_MIN_SRC_W 8
>  #define SKL_MAX_SRC_W 4096
>  #define SKL_MIN_SRC_H 8
> -#define SKL_MAX_SRC_H 2304
> +#define SKL_MAX_SRC_H 4096
>  #define SKL_MIN_DST_W 8
>  #define SKL_MAX_DST_W 4096
>  #define SKL_MIN_DST_H 8
> -#define SKL_MAX_DST_H 2304
> +#define SKL_MAX_DST_H 4096
> 
>  struct intel_scaler {
>  	int id;
> @@ -1131,9 +1131,13 @@ void skl_detach_scalers(struct intel_crtc *intel_crtc);
>  int skl_update_scaler_users(struct intel_crtc *intel_crtc,
>  	struct intel_crtc_state *crtc_state, struct intel_plane *intel_plane,
>  	struct intel_plane_state *plane_state, int force_detach);
> +int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state);
> 
>  unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
>  				     struct drm_i915_gem_object *obj);
> +u32 skl_plane_ctl_format(uint32_t pixel_format);
> +u32 skl_plane_ctl_tiling(uint64_t fb_modifier);
> +u32 skl_plane_ctl_rotation(unsigned int rotation);
> 
>  /* intel_dp.c */
>  void intel_dp_init(struct drm_device *dev, int output_reg, enum port port);
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c
> b/drivers/gpu/drm/i915/intel_sprite.c
> index 0cb3767..2f42777 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -1150,6 +1150,15 @@ int intel_sprite_set_colorkey(struct drm_device
> *dev, void *data,
>  	}
> 
>  	intel_plane = to_intel_plane(plane);
> +
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		/* plane scaling and colorkey are mutually exclusive */
> +		if (to_intel_plane_state(plane->state)->scaler_id >= 0) {
> +			DRM_ERROR("colorkey not allowed with scaler\n");
> +			return -EINVAL;
> +		}
> +	}
> +
>  	intel_plane->ckey = *set;
> 
>  	/*
> --
> 1.7.9.5

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

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

* Re: [PATCH 13/14] drm/i915: skylake primary plane scaling using shared scalers
  2015-04-15 22:14   ` Chandra Konduru
  2015-04-15 23:08     ` Konduru, Chandra
@ 2015-04-16  7:36     ` Daniel Vetter
  2015-04-16  8:17     ` Jindal, Sonika
  2015-04-23 20:20     ` Daniel Vetter
  3 siblings, 0 replies; 54+ messages in thread
From: Daniel Vetter @ 2015-04-16  7:36 UTC (permalink / raw)
  To: Chandra Konduru; +Cc: daniel.vetter, intel-gfx, ander.conselvan.de.oliveira

On Wed, Apr 15, 2015 at 03:14:38PM -0700, Chandra Konduru wrote:
> This patch enables skylake primary plane scaling using shared
> scalers atomic desgin.
> 
> v2:
> -use single copy of scaler limits (Matt)
> 
> v3:
> -move detach_scalers to crtc commit path (Matt)
> -use values in plane_state->src as regular integers (me)
> 
> v4:
> -changes to align with updated scaler structures (Matt, me)
> -keep plane src rect in 16.16 format (Matt, Daniel)
> 
> v5:
> -Rebased on top of 90/270 rotation changes (me)
> -Fixed an issue introduced by 90/270 changes where plane programming
>  is using drm_plane->state rect instead of intel_plane->state rect.
>  This change also required for scaling to work properly. (me)
> -With 90/270, updated limits to cover both portrait and landscape usages (me)
> -Refactored skylake_update_primary_plane to reduce its size (Daniel)
>  Added helper functions for refactoring are comprehended enough to be
>  used for skylake_update_plane (for sprite) too. One stop towards
>  having single function for all planes.

Please split out the refactoring into a prep patch since it's really hard
to review for functional changes when the code moves around. But when
that's split into a pure code-motion patch (which shouldn't have any
functional changes) and a subsequent patch to actually change the logic
then everything's a lot clearer. My BKM for splitting out prep patches is:

1. Create a new branch based on drm-intel-nightly.
2. Extract the first refactor step: You can either cherry-pick parts of
the patch or create it anew. Don't bother thinking about conflicts. Test
this patch to make sure you don't introduce a bisect issue.
3. Commit a revert of your refactor patch.
4. Cherry-pick the original patch, it should apply cleanly because the
baseline is unchanged due to the revert.
5. You now have 3 patches in your branch
	- refactor patch
	- Revert "refactor patch"
	- real patch you want to split up
Now do a rebase and squash together the Revert and the real patch.
-> First step is cleanly split out without ever having to deal with
conflicts or risking bisectability issues. Your branch has now 2 patches:
	- refactor patch
	- real patch with refactor parts taken out

Repeat until you've split up the patch into all the different parts.

Cheers, Daniel
> 
> Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
> Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
> Testcase: kms_plane_scaling
> ---
>  drivers/gpu/drm/i915/intel_atomic.c  |    5 +-
>  drivers/gpu/drm/i915/intel_display.c |  261 +++++++++++++++++++++++++---------
>  drivers/gpu/drm/i915/intel_drv.h     |    8 +-
>  drivers/gpu/drm/i915/intel_sprite.c  |    9 ++
>  4 files changed, 213 insertions(+), 70 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> index 3c4b7cd..cb6d5f2 100644
> --- a/drivers/gpu/drm/i915/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> @@ -169,7 +169,7 @@ int intel_atomic_commit(struct drm_device *dev,
>  		plane->state->state = NULL;
>  	}
>  
> -	/* swap crtc_state */
> +	/* swap crtc_scaler_state */
>  	for (i = 0; i < dev->mode_config.num_crtc; i++) {
>  		struct drm_crtc *crtc = state->crtcs[i];
>  		if (!crtc) {
> @@ -178,6 +178,9 @@ int intel_atomic_commit(struct drm_device *dev,
>  
>  		to_intel_crtc(crtc)->config->scaler_state =
>  			to_intel_crtc_state(state->crtc_states[i])->scaler_state;
> +
> +		if (INTEL_INFO(dev)->gen >= 9)
> +			skl_detach_scalers(to_intel_crtc(crtc));
>  	}
>  
>  	drm_atomic_helper_commit_planes(dev, state);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 5f7a40f..7f3ae8e 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2960,126 +2960,199 @@ void skl_detach_scalers(struct intel_crtc *intel_crtc)
>  	}
>  }
>  
> -static void skylake_update_primary_plane(struct drm_crtc *crtc,
> -					 struct drm_framebuffer *fb,
> -					 int x, int y)
> +u32 skl_plane_ctl_format(uint32_t pixel_format)
>  {
> -	struct drm_device *dev = crtc->dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -	struct drm_i915_gem_object *obj;
> -	int pipe = intel_crtc->pipe;
> -	u32 plane_ctl, stride_div, stride;
> -	u32 tile_height, plane_offset, plane_size;
> -	unsigned int rotation;
> -	int x_offset, y_offset;
> -	unsigned long surf_addr;
> -	struct drm_plane *plane;
> -
> -	if (!intel_crtc->primary_enabled) {
> -		I915_WRITE(PLANE_CTL(pipe, 0), 0);
> -		I915_WRITE(PLANE_SURF(pipe, 0), 0);
> -		POSTING_READ(PLANE_CTL(pipe, 0));
> -		return;
> -	}
> -
> -	plane_ctl = PLANE_CTL_ENABLE |
> -		    PLANE_CTL_PIPE_GAMMA_ENABLE |
> -		    PLANE_CTL_PIPE_CSC_ENABLE;
> -
> -	switch (fb->pixel_format) {
> +	u32 plane_ctl_format = 0;
> +	switch (pixel_format) {
>  	case DRM_FORMAT_RGB565:
> -		plane_ctl |= PLANE_CTL_FORMAT_RGB_565;
> -		break;
> -	case DRM_FORMAT_XRGB8888:
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> -		break;
> -	case DRM_FORMAT_ARGB8888:
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> -		plane_ctl |= PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> +		plane_ctl_format = PLANE_CTL_FORMAT_RGB_565;
>  		break;
>  	case DRM_FORMAT_XBGR8888:
> -		plane_ctl |= PLANE_CTL_ORDER_RGBX;
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
>  		break;
> +	case DRM_FORMAT_XRGB8888:
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888;
> +		break;
> +	/*
> +	 * XXX: For ARBG/ABGR formats we default to expecting scanout buffers
> +	 * to be already pre-multiplied. We need to add a knob (or a different
> +	 * DRM_FORMAT) for user-space to configure that.
> +	 */
>  	case DRM_FORMAT_ABGR8888:
> -		plane_ctl |= PLANE_CTL_ORDER_RGBX;
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> -		plane_ctl |= PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX |
> +			PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> +		break;
> +	case DRM_FORMAT_ARGB8888:
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 |
> +			PLANE_CTL_ALPHA_SW_PREMULTIPLY;
>  		break;
>  	case DRM_FORMAT_XRGB2101010:
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010;
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_2101010;
>  		break;
>  	case DRM_FORMAT_XBGR2101010:
> -		plane_ctl |= PLANE_CTL_ORDER_RGBX;
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010;
> +		plane_ctl_format = PLANE_CTL_ORDER_RGBX | PLANE_CTL_FORMAT_XRGB_2101010;
> +		break;
> +	case DRM_FORMAT_YUYV:
> +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV;
> +		break;
> +	case DRM_FORMAT_YVYU:
> +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU;
> +		break;
> +	case DRM_FORMAT_UYVY:
> +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY;
> +		break;
> +	case DRM_FORMAT_VYUY:
> +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
>  		break;
>  	default:
>  		BUG();
>  	}
> +	return plane_ctl_format;
> +}
>  
> -	switch (fb->modifier[0]) {
> +u32 skl_plane_ctl_tiling(uint64_t fb_modifier)
> +{
> +	u32 plane_ctl_tiling = 0;
> +	switch (fb_modifier) {
>  	case DRM_FORMAT_MOD_NONE:
>  		break;
>  	case I915_FORMAT_MOD_X_TILED:
> -		plane_ctl |= PLANE_CTL_TILED_X;
> +		plane_ctl_tiling = PLANE_CTL_TILED_X;
>  		break;
>  	case I915_FORMAT_MOD_Y_TILED:
> -		plane_ctl |= PLANE_CTL_TILED_Y;
> +		plane_ctl_tiling = PLANE_CTL_TILED_Y;
>  		break;
>  	case I915_FORMAT_MOD_Yf_TILED:
> -		plane_ctl |= PLANE_CTL_TILED_YF;
> +		plane_ctl_tiling = PLANE_CTL_TILED_YF;
>  		break;
>  	default:
> -		MISSING_CASE(fb->modifier[0]);
> +		MISSING_CASE(fb_modifier);
>  	}
> +	return plane_ctl_tiling;
> +}
>  
> -	plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
> -
> -	plane = crtc->primary;
> -	rotation = plane->state->rotation;
> +u32 skl_plane_ctl_rotation(unsigned int rotation)
> +{
> +	u32 plane_ctl_rotation = 0;
>  	switch (rotation) {
> +	case BIT(DRM_ROTATE_0):
> +		break;
>  	case BIT(DRM_ROTATE_90):
> -		plane_ctl |= PLANE_CTL_ROTATE_90;
> +		plane_ctl_rotation = PLANE_CTL_ROTATE_90;
>  		break;
> -
>  	case BIT(DRM_ROTATE_180):
> -		plane_ctl |= PLANE_CTL_ROTATE_180;
> +		plane_ctl_rotation = PLANE_CTL_ROTATE_180;
>  		break;
> -
>  	case BIT(DRM_ROTATE_270):
> -		plane_ctl |= PLANE_CTL_ROTATE_270;
> +		plane_ctl_rotation = PLANE_CTL_ROTATE_270;
>  		break;
> +	default:
> +		MISSING_CASE(rotation);
>  	}
>  
> +	return plane_ctl_rotation;
> +}
> +
> +static void skylake_update_primary_plane(struct drm_crtc *crtc,
> +					 struct drm_framebuffer *fb,
> +					 int x, int y)
> +{
> +	struct drm_device *dev = crtc->dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct drm_i915_gem_object *obj;
> +	int pipe = intel_crtc->pipe;
> +	u32 plane_ctl, stride_div, stride;
> +	u32 tile_height, plane_offset, plane_size;
> +	unsigned int rotation;
> +	int x_offset, y_offset;
> +	unsigned long surf_addr;
> +	struct drm_plane *plane;
> +	struct intel_crtc_state *crtc_state = intel_crtc->config;
> +	struct intel_plane_state *plane_state;
> +	int src_x = 0, src_y = 0, src_w = 0, src_h = 0;
> +	int dst_x = 0, dst_y = 0, dst_w = 0, dst_h = 0;
> +	int scaler_id = -1;
> +
> +	plane = crtc->primary;
> +	plane_state = plane ? to_intel_plane_state(crtc->primary->state) : NULL;
> +
> +	if (!intel_crtc->primary_enabled) {
> +		I915_WRITE(PLANE_CTL(pipe, 0), 0);
> +		I915_WRITE(PLANE_SURF(pipe, 0), 0);
> +		POSTING_READ(PLANE_CTL(pipe, 0));
> +		return;
> +	}
> +
> +	plane_ctl = PLANE_CTL_ENABLE |
> +		    PLANE_CTL_PIPE_GAMMA_ENABLE |
> +		    PLANE_CTL_PIPE_CSC_ENABLE;
> +
> +	plane_ctl |= skl_plane_ctl_format(fb->pixel_format);
> +	plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]);
> +	plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
> +
> +	rotation = plane->state->rotation;
> +	plane_ctl |= skl_plane_ctl_rotation(rotation);
> +
>  	obj = intel_fb_obj(fb);
>  	stride_div = intel_fb_stride_alignment(dev, fb->modifier[0],
>  					       fb->pixel_format);
>  	surf_addr = intel_plane_obj_offset(to_intel_plane(plane), obj);
>  
> +	if (plane_state && drm_rect_width(&plane_state->src)) {
> +		scaler_id = plane_state->scaler_id;
> +		src_x = plane_state->src.x1 >> 16;
> +		src_y = plane_state->src.y1 >> 16;
> +		src_w = drm_rect_width(&plane_state->src) >> 16;
> +		src_h = drm_rect_height(&plane_state->src) >> 16;
> +		dst_x = plane_state->dst.x1;
> +		dst_y = plane_state->dst.y1;
> +		dst_w = drm_rect_width(&plane_state->dst);
> +		dst_h = drm_rect_height(&plane_state->dst);
> +
> +		WARN_ON(x != src_x || y != src_y);
> +	} else {
> +		src_w = intel_crtc->config->pipe_src_w;
> +		src_h = intel_crtc->config->pipe_src_h;
> +	}
> +
>  	if (intel_rotation_90_or_270(rotation)) {
>  		/* stride = Surface height in tiles */
>  		tile_height = intel_tile_height(dev, fb->bits_per_pixel,
>  						fb->modifier[0]);
>  		stride = DIV_ROUND_UP(fb->height, tile_height);
> -		x_offset = stride * tile_height - y - (plane->state->src_h >> 16);
> +		x_offset = stride * tile_height - y - src_h;
>  		y_offset = x;
> -		plane_size = ((plane->state->src_w >> 16) - 1) << 16 |
> -					((plane->state->src_h >> 16) - 1);
> +		plane_size = (src_w - 1) << 16 | (src_h - 1);
>  	} else {
>  		stride = fb->pitches[0] / stride_div;
>  		x_offset = x;
>  		y_offset = y;
> -		plane_size = ((plane->state->src_h >> 16) - 1) << 16 |
> -			((plane->state->src_w >> 16) - 1);
> +		plane_size = (src_h - 1) << 16 | (src_w - 1);
>  	}
>  	plane_offset = y_offset << 16 | x_offset;
>  
>  	I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
> -	I915_WRITE(PLANE_POS(pipe, 0), 0);
>  	I915_WRITE(PLANE_OFFSET(pipe, 0), plane_offset);
>  	I915_WRITE(PLANE_SIZE(pipe, 0), plane_size);
>  	I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
> +
> +	if (scaler_id >= 0) {
> +		uint32_t ps_ctrl = 0;
> +
> +		WARN_ON(!dst_w || !dst_h);
> +		ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(0) |
> +			crtc_state->scaler_state.scalers[scaler_id].mode;
> +		I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
> +		I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
> +		I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (dst_x << 16) | dst_y);
> +		I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id), (dst_w << 16) | dst_h);
> +		I915_WRITE(PLANE_POS(pipe, 0), 0);
> +	} else {
> +		I915_WRITE(PLANE_POS(pipe, 0), (dst_y << 16) | dst_x);
> +	}
> +
>  	I915_WRITE(PLANE_SURF(pipe, 0), surf_addr);
>  
>  	POSTING_READ(PLANE_SURF(pipe, 0));
> @@ -4338,6 +4411,7 @@ skl_update_scaler_users(
>  	int *scaler_id;
>  	struct drm_framebuffer *fb;
>  	struct intel_crtc_scaler_state *scaler_state;
> +	unsigned int rotation;
>  
>  	if (!intel_crtc || !crtc_state)
>  		return 0;
> @@ -4353,6 +4427,7 @@ skl_update_scaler_users(
>  		dst_w = drm_rect_width(&plane_state->dst);
>  		dst_h = drm_rect_height(&plane_state->dst);
>  		scaler_id = &plane_state->scaler_id;
> +		rotation = plane_state->base.rotation;
>  	} else {
>  		struct drm_display_mode *adjusted_mode =
>  			&crtc_state->base.adjusted_mode;
> @@ -4361,8 +4436,12 @@ skl_update_scaler_users(
>  		dst_w = adjusted_mode->hdisplay;
>  		dst_h = adjusted_mode->vdisplay;
>  		scaler_id = &scaler_state->scaler_id;
> +		rotation = DRM_ROTATE_0;
>  	}
> -	need_scaling = (src_w != dst_w || src_h != dst_h);
> +
> +	need_scaling = intel_rotation_90_or_270(rotation) ?
> +		(src_h != dst_w || src_w != dst_h):
> +		(src_w != dst_w || src_h != dst_h);
>  
>  	/*
>  	 * if plane is being disabled or scaler is no more required or force detach
> @@ -12805,6 +12884,36 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
>  	}
>  }
>  
> +int
> +skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state)
> +{
> +	int max_scale;
> +	struct drm_device *dev;
> +	struct drm_i915_private *dev_priv;
> +	int crtc_clock, cdclk;
> +
> +	if (!intel_crtc || !crtc_state)
> +		return DRM_PLANE_HELPER_NO_SCALING;
> +
> +	dev = intel_crtc->base.dev;
> +	dev_priv = dev->dev_private;
> +	crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
> +	cdclk = dev_priv->display.get_display_clock_speed(dev);
> +
> +	if (!crtc_clock || !cdclk)
> +		return DRM_PLANE_HELPER_NO_SCALING;
> +
> +	/*
> +	 * skl max scale is lower of:
> +	 *    close to 3 but not 3, -1 is for that purpose
> +	 *            or
> +	 *    cdclk/crtc_clock
> +	 */
> +	max_scale = min((1 << 16) * 3 - 1, (1 << 8) * ((cdclk << 8) / crtc_clock));
> +
> +	return max_scale;
> +}
> +
>  static int
>  intel_check_primary_plane(struct drm_plane *plane,
>  			  struct intel_plane_state *state)
> @@ -12813,23 +12922,31 @@ intel_check_primary_plane(struct drm_plane *plane,
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct drm_crtc *crtc = state->base.crtc;
>  	struct intel_crtc *intel_crtc;
> +	struct intel_crtc_state *crtc_state;
>  	struct drm_framebuffer *fb = state->base.fb;
>  	struct drm_rect *dest = &state->dst;
>  	struct drm_rect *src = &state->src;
>  	const struct drm_rect *clip = &state->clip;
>  	bool can_position = false;
> +	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
> +	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
>  	int ret;
>  
>  	crtc = crtc ? crtc : plane->crtc;
>  	intel_crtc = to_intel_crtc(crtc);
> +	crtc_state = state->base.state ?
> +		intel_atomic_get_crtc_state(state->base.state, intel_crtc) : NULL;
>  
> -	if (INTEL_INFO(dev)->gen >= 9)
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		min_scale = 1;
> +		max_scale = skl_max_scale(intel_crtc, crtc_state);
>  		can_position = true;
> +	}
>  
>  	ret = drm_plane_helper_check_update(plane, crtc, fb,
>  					    src, dest, clip,
> -					    DRM_PLANE_HELPER_NO_SCALING,
> -					    DRM_PLANE_HELPER_NO_SCALING,
> +					    min_scale,
> +					    max_scale,
>  					    can_position, true,
>  					    &state->visible);
>  	if (ret)
> @@ -12874,6 +12991,13 @@ intel_check_primary_plane(struct drm_plane *plane,
>  			intel_crtc->atomic.update_wm = true;
>  	}
>  
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		ret = skl_update_scaler_users(intel_crtc, crtc_state,
> +			to_intel_plane(plane), state, 0);
> +		if (ret)
> +			return ret;
> +	}
> +
>  	return 0;
>  }
>  
> @@ -13053,6 +13177,9 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
>  
>  	primary->can_scale = false;
>  	primary->max_downscale = 1;
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		primary->can_scale = true;
> +	}
>  	state->scaler_id = -1;
>  	primary->pipe = pipe;
>  	primary->plane = pipe;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 275a4ef..c9bc975 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -288,11 +288,11 @@ struct intel_initial_plane_config {
>  #define SKL_MIN_SRC_W 8
>  #define SKL_MAX_SRC_W 4096
>  #define SKL_MIN_SRC_H 8
> -#define SKL_MAX_SRC_H 2304
> +#define SKL_MAX_SRC_H 4096
>  #define SKL_MIN_DST_W 8
>  #define SKL_MAX_DST_W 4096
>  #define SKL_MIN_DST_H 8
> -#define SKL_MAX_DST_H 2304
> +#define SKL_MAX_DST_H 4096
>  
>  struct intel_scaler {
>  	int id;
> @@ -1131,9 +1131,13 @@ void skl_detach_scalers(struct intel_crtc *intel_crtc);
>  int skl_update_scaler_users(struct intel_crtc *intel_crtc,
>  	struct intel_crtc_state *crtc_state, struct intel_plane *intel_plane,
>  	struct intel_plane_state *plane_state, int force_detach);
> +int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state);
>  
>  unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
>  				     struct drm_i915_gem_object *obj);
> +u32 skl_plane_ctl_format(uint32_t pixel_format);
> +u32 skl_plane_ctl_tiling(uint64_t fb_modifier);
> +u32 skl_plane_ctl_rotation(unsigned int rotation);
>  
>  /* intel_dp.c */
>  void intel_dp_init(struct drm_device *dev, int output_reg, enum port port);
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 0cb3767..2f42777 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -1150,6 +1150,15 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
>  	}
>  
>  	intel_plane = to_intel_plane(plane);
> +
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		/* plane scaling and colorkey are mutually exclusive */
> +		if (to_intel_plane_state(plane->state)->scaler_id >= 0) {
> +			DRM_ERROR("colorkey not allowed with scaler\n");
> +			return -EINVAL;
> +		}
> +	}
> +
>  	intel_plane->ckey = *set;
>  
>  	/*
> -- 
> 1.7.9.5
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 14/14] drm/i915: skylake sprite plane scaling using shared scalers
  2015-04-15 22:15   ` Chandra Konduru
@ 2015-04-16  7:42     ` Daniel Vetter
  2015-04-16  8:18     ` Jindal, Sonika
  1 sibling, 0 replies; 54+ messages in thread
From: Daniel Vetter @ 2015-04-16  7:42 UTC (permalink / raw)
  To: Chandra Konduru; +Cc: daniel.vetter, intel-gfx, ander.conselvan.de.oliveira

On Wed, Apr 15, 2015 at 03:15:02PM -0700, Chandra Konduru wrote:
> This patch enables skylake sprite plane display scaling using shared
> scalers atomic desgin.
> 
> v2:
> -use single copy of scaler limits (Matt)
> 
> v3:
> -detaching scalers moved to crtc commit path (Matt)
> 
> v4:
> -changes to align with updated scaler structures (Matt, me)
> -keep sprite src rect in 16.16 format (Matt, Daniel)
> 
> v5:
> -rebased on top of 90/270 rotation changes (me)
> -Refactored skl_update_plane to reduce its size (Daniel)
>  It is a step towards having a single function covering all planes.

Same here, please don't mix up refactorings (or just plain code motion)
with functional changes.
-Daniel

> 
> Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
> Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
> Testcase: kms_plane_scaling
> ---
>  drivers/gpu/drm/i915/intel_sprite.c |  125 ++++++++++++++---------------------
>  1 file changed, 48 insertions(+), 77 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 2f42777..497bc1d 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -33,6 +33,7 @@
>  #include <drm/drm_crtc.h>
>  #include <drm/drm_fourcc.h>
>  #include <drm/drm_rect.h>
> +#include <drm/drm_atomic.h>
>  #include <drm/drm_plane_helper.h>
>  #include "intel_drv.h"
>  #include <drm/i915_drm.h>
> @@ -197,80 +198,17 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
>  	u32 tile_height, plane_offset, plane_size;
>  	unsigned int rotation;
>  	int x_offset, y_offset;
> +	struct intel_crtc_state *crtc_state = to_intel_crtc(crtc)->config;
> +	int scaler_id;
>  
>  	plane_ctl = PLANE_CTL_ENABLE |
>  		PLANE_CTL_PIPE_CSC_ENABLE;
>  
> -	switch (fb->pixel_format) {
> -	case DRM_FORMAT_RGB565:
> -		plane_ctl |= PLANE_CTL_FORMAT_RGB_565;
> -		break;
> -	case DRM_FORMAT_XBGR8888:
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
> -		break;
> -	case DRM_FORMAT_XRGB8888:
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> -		break;
> -	/*
> -	 * XXX: For ARBG/ABGR formats we default to expecting scanout buffers
> -	 * to be already pre-multiplied. We need to add a knob (or a different
> -	 * DRM_FORMAT) for user-space to configure that.
> -	 */
> -	case DRM_FORMAT_ABGR8888:
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 |
> -			     PLANE_CTL_ORDER_RGBX |
> -			     PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> -		break;
> -	case DRM_FORMAT_ARGB8888:
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 |
> -			     PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> -		break;
> -	case DRM_FORMAT_YUYV:
> -		plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV;
> -		break;
> -	case DRM_FORMAT_YVYU:
> -		plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU;
> -		break;
> -	case DRM_FORMAT_UYVY:
> -		plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY;
> -		break;
> -	case DRM_FORMAT_VYUY:
> -		plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
> -		break;
> -	default:
> -		BUG();
> -	}
> -
> -	switch (fb->modifier[0]) {
> -	case DRM_FORMAT_MOD_NONE:
> -		break;
> -	case I915_FORMAT_MOD_X_TILED:
> -		plane_ctl |= PLANE_CTL_TILED_X;
> -		break;
> -	case I915_FORMAT_MOD_Y_TILED:
> -		plane_ctl |= PLANE_CTL_TILED_Y;
> -		break;
> -	case I915_FORMAT_MOD_Yf_TILED:
> -		plane_ctl |= PLANE_CTL_TILED_YF;
> -		break;
> -	default:
> -		MISSING_CASE(fb->modifier[0]);
> -	}
> +	plane_ctl |= skl_plane_ctl_format(fb->pixel_format);
> +	plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]);
>  
>  	rotation = drm_plane->state->rotation;
> -	switch (rotation) {
> -	case BIT(DRM_ROTATE_90):
> -		plane_ctl |= PLANE_CTL_ROTATE_90;
> -		break;
> -
> -	case BIT(DRM_ROTATE_180):
> -		plane_ctl |= PLANE_CTL_ROTATE_180;
> -		break;
> -
> -	case BIT(DRM_ROTATE_270):
> -		plane_ctl |= PLANE_CTL_ROTATE_270;
> -		break;
> -	}
> +	plane_ctl |= skl_plane_ctl_rotation(rotation);
>  
>  	intel_update_sprite_watermarks(drm_plane, crtc, src_w, src_h,
>  				       pixel_size, true,
> @@ -279,6 +217,8 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
>  	stride_div = intel_fb_stride_alignment(dev, fb->modifier[0],
>  					       fb->pixel_format);
>  
> +	scaler_id = to_intel_plane_state(drm_plane->state)->scaler_id;
> +
>  	/* Sizes are 0 based */
>  	src_w--;
>  	src_h--;
> @@ -316,8 +256,27 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
>  
>  	I915_WRITE(PLANE_OFFSET(pipe, plane), plane_offset);
>  	I915_WRITE(PLANE_STRIDE(pipe, plane), stride);
> -	I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x);
>  	I915_WRITE(PLANE_SIZE(pipe, plane), plane_size);
> +
> +	/* program plane scaler */
> +	if (scaler_id >= 0) {
> +		uint32_t ps_ctrl = 0;
> +
> +		DRM_DEBUG_KMS("plane = %d PS_PLANE_SEL(plane) = 0x%x\n", plane,
> +			PS_PLANE_SEL(plane));
> +		ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(plane) |
> +			crtc_state->scaler_state.scalers[scaler_id].mode;
> +		I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
> +		I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
> +		I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
> +		I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id),
> +			((crtc_w + 1) << 16)|(crtc_h + 1));
> +
> +		I915_WRITE(PLANE_POS(pipe, plane), 0);
> +	} else {
> +		I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x);
> +	}
> +
>  	I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl);
>  	I915_WRITE(PLANE_SURF(pipe, plane), surf_addr);
>  	POSTING_READ(PLANE_SURF(pipe, plane));
> @@ -894,7 +853,9 @@ static int
>  intel_check_sprite_plane(struct drm_plane *plane,
>  			 struct intel_plane_state *state)
>  {
> +	struct drm_device *dev = plane->dev;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(state->base.crtc);
> +	struct intel_crtc_state *crtc_state;
>  	struct intel_plane *intel_plane = to_intel_plane(plane);
>  	struct drm_framebuffer *fb = state->base.fb;
>  	int crtc_x, crtc_y;
> @@ -906,8 +867,11 @@ intel_check_sprite_plane(struct drm_plane *plane,
>  	int hscale, vscale;
>  	int max_scale, min_scale;
>  	int pixel_size;
> +	int ret;
>  
>  	intel_crtc = intel_crtc ? intel_crtc : to_intel_crtc(plane->crtc);
> +	crtc_state = state->base.state ?
> +		intel_atomic_get_crtc_state(state->base.state, intel_crtc) : NULL;
>  
>  	if (!fb) {
>  		state->visible = false;
> @@ -934,6 +898,11 @@ intel_check_sprite_plane(struct drm_plane *plane,
>  	max_scale = intel_plane->max_downscale << 16;
>  	min_scale = intel_plane->can_scale ? 1 : (1 << 16);
>  
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		min_scale = 1;
> +		max_scale = skl_max_scale(intel_crtc, crtc_state);
> +	}
> +
>  	drm_rect_rotate(src, fb->width << 16, fb->height << 16,
>  			state->base.rotation);
>  
> @@ -1029,8 +998,8 @@ intel_check_sprite_plane(struct drm_plane *plane,
>  		width_bytes = ((src_x * pixel_size) & 63) +
>  					src_w * pixel_size;
>  
> -		if (src_w > 2048 || src_h > 2048 ||
> -		    width_bytes > 4096 || fb->pitches[0] > 4096) {
> +		if (INTEL_INFO(dev)->gen < 9 && (src_w > 2048 || src_h > 2048 ||
> +		    width_bytes > 4096 || fb->pitches[0] > 4096)) {
>  			DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
>  			return -EINVAL;
>  		}
> @@ -1084,6 +1053,13 @@ finish:
>  		}
>  	}
>  
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		ret = skl_update_scaler_users(intel_crtc, crtc_state, intel_plane,
> +			state, 0);
> +		if (ret)
> +			return ret;
> +	}
> +
>  	return 0;
>  }
>  
> @@ -1295,12 +1271,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
>  		}
>  		break;
>  	case 9:
> -		/*
> -		 * FIXME: Skylake planes can be scaled (with some restrictions),
> -		 * but this is for another time.
> -		 */
> -		intel_plane->can_scale = false;
> -		intel_plane->max_downscale = 1;
> +		intel_plane->can_scale = true;
>  		intel_plane->update_plane = skl_update_plane;
>  		intel_plane->disable_plane = skl_disable_plane;
>  		state->scaler_id = -1;
> -- 
> 1.7.9.5
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 13/14] drm/i915: skylake primary plane scaling using shared scalers
  2015-04-15 22:14   ` Chandra Konduru
  2015-04-15 23:08     ` Konduru, Chandra
  2015-04-16  7:36     ` Daniel Vetter
@ 2015-04-16  8:17     ` Jindal, Sonika
  2015-04-23 20:20     ` Daniel Vetter
  3 siblings, 0 replies; 54+ messages in thread
From: Jindal, Sonika @ 2015-04-16  8:17 UTC (permalink / raw)
  To: Chandra Konduru, intel-gfx; +Cc: daniel.vetter, ander.conselvan.de.oliveira

For v5:

Reviewed-by: Sonika Jindal <sonika.jindal@intel.com> (v5)

Regards,
Sonika

On 4/16/2015 3:44 AM, Chandra Konduru wrote:
> This patch enables skylake primary plane scaling using shared
> scalers atomic desgin.
>
> v2:
> -use single copy of scaler limits (Matt)
>
> v3:
> -move detach_scalers to crtc commit path (Matt)
> -use values in plane_state->src as regular integers (me)
>
> v4:
> -changes to align with updated scaler structures (Matt, me)
> -keep plane src rect in 16.16 format (Matt, Daniel)
>
> v5:
> -Rebased on top of 90/270 rotation changes (me)
> -Fixed an issue introduced by 90/270 changes where plane programming
>   is using drm_plane->state rect instead of intel_plane->state rect.
>   This change also required for scaling to work properly. (me)
> -With 90/270, updated limits to cover both portrait and landscape usages (me)
> -Refactored skylake_update_primary_plane to reduce its size (Daniel)
>   Added helper functions for refactoring are comprehended enough to be
>   used for skylake_update_plane (for sprite) too. One stop towards
>   having single function for all planes.
>
> Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
> Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
> Testcase: kms_plane_scaling
> ---
>   drivers/gpu/drm/i915/intel_atomic.c  |    5 +-
>   drivers/gpu/drm/i915/intel_display.c |  261 +++++++++++++++++++++++++---------
>   drivers/gpu/drm/i915/intel_drv.h     |    8 +-
>   drivers/gpu/drm/i915/intel_sprite.c  |    9 ++
>   4 files changed, 213 insertions(+), 70 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> index 3c4b7cd..cb6d5f2 100644
> --- a/drivers/gpu/drm/i915/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> @@ -169,7 +169,7 @@ int intel_atomic_commit(struct drm_device *dev,
>   		plane->state->state = NULL;
>   	}
>
> -	/* swap crtc_state */
> +	/* swap crtc_scaler_state */
>   	for (i = 0; i < dev->mode_config.num_crtc; i++) {
>   		struct drm_crtc *crtc = state->crtcs[i];
>   		if (!crtc) {
> @@ -178,6 +178,9 @@ int intel_atomic_commit(struct drm_device *dev,
>
>   		to_intel_crtc(crtc)->config->scaler_state =
>   			to_intel_crtc_state(state->crtc_states[i])->scaler_state;
> +
> +		if (INTEL_INFO(dev)->gen >= 9)
> +			skl_detach_scalers(to_intel_crtc(crtc));
>   	}
>
>   	drm_atomic_helper_commit_planes(dev, state);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 5f7a40f..7f3ae8e 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2960,126 +2960,199 @@ void skl_detach_scalers(struct intel_crtc *intel_crtc)
>   	}
>   }
>
> -static void skylake_update_primary_plane(struct drm_crtc *crtc,
> -					 struct drm_framebuffer *fb,
> -					 int x, int y)
> +u32 skl_plane_ctl_format(uint32_t pixel_format)
>   {
> -	struct drm_device *dev = crtc->dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -	struct drm_i915_gem_object *obj;
> -	int pipe = intel_crtc->pipe;
> -	u32 plane_ctl, stride_div, stride;
> -	u32 tile_height, plane_offset, plane_size;
> -	unsigned int rotation;
> -	int x_offset, y_offset;
> -	unsigned long surf_addr;
> -	struct drm_plane *plane;
> -
> -	if (!intel_crtc->primary_enabled) {
> -		I915_WRITE(PLANE_CTL(pipe, 0), 0);
> -		I915_WRITE(PLANE_SURF(pipe, 0), 0);
> -		POSTING_READ(PLANE_CTL(pipe, 0));
> -		return;
> -	}
> -
> -	plane_ctl = PLANE_CTL_ENABLE |
> -		    PLANE_CTL_PIPE_GAMMA_ENABLE |
> -		    PLANE_CTL_PIPE_CSC_ENABLE;
> -
> -	switch (fb->pixel_format) {
> +	u32 plane_ctl_format = 0;
> +	switch (pixel_format) {
>   	case DRM_FORMAT_RGB565:
> -		plane_ctl |= PLANE_CTL_FORMAT_RGB_565;
> -		break;
> -	case DRM_FORMAT_XRGB8888:
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> -		break;
> -	case DRM_FORMAT_ARGB8888:
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> -		plane_ctl |= PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> +		plane_ctl_format = PLANE_CTL_FORMAT_RGB_565;
>   		break;
>   	case DRM_FORMAT_XBGR8888:
> -		plane_ctl |= PLANE_CTL_ORDER_RGBX;
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
>   		break;
> +	case DRM_FORMAT_XRGB8888:
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888;
> +		break;
> +	/*
> +	 * XXX: For ARBG/ABGR formats we default to expecting scanout buffers
> +	 * to be already pre-multiplied. We need to add a knob (or a different
> +	 * DRM_FORMAT) for user-space to configure that.
> +	 */
>   	case DRM_FORMAT_ABGR8888:
> -		plane_ctl |= PLANE_CTL_ORDER_RGBX;
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> -		plane_ctl |= PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX |
> +			PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> +		break;
> +	case DRM_FORMAT_ARGB8888:
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 |
> +			PLANE_CTL_ALPHA_SW_PREMULTIPLY;
>   		break;
>   	case DRM_FORMAT_XRGB2101010:
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010;
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_2101010;
>   		break;
>   	case DRM_FORMAT_XBGR2101010:
> -		plane_ctl |= PLANE_CTL_ORDER_RGBX;
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010;
> +		plane_ctl_format = PLANE_CTL_ORDER_RGBX | PLANE_CTL_FORMAT_XRGB_2101010;
> +		break;
> +	case DRM_FORMAT_YUYV:
> +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV;
> +		break;
> +	case DRM_FORMAT_YVYU:
> +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU;
> +		break;
> +	case DRM_FORMAT_UYVY:
> +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY;
> +		break;
> +	case DRM_FORMAT_VYUY:
> +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
>   		break;
>   	default:
>   		BUG();
>   	}
> +	return plane_ctl_format;
> +}
>
> -	switch (fb->modifier[0]) {
> +u32 skl_plane_ctl_tiling(uint64_t fb_modifier)
> +{
> +	u32 plane_ctl_tiling = 0;
> +	switch (fb_modifier) {
>   	case DRM_FORMAT_MOD_NONE:
>   		break;
>   	case I915_FORMAT_MOD_X_TILED:
> -		plane_ctl |= PLANE_CTL_TILED_X;
> +		plane_ctl_tiling = PLANE_CTL_TILED_X;
>   		break;
>   	case I915_FORMAT_MOD_Y_TILED:
> -		plane_ctl |= PLANE_CTL_TILED_Y;
> +		plane_ctl_tiling = PLANE_CTL_TILED_Y;
>   		break;
>   	case I915_FORMAT_MOD_Yf_TILED:
> -		plane_ctl |= PLANE_CTL_TILED_YF;
> +		plane_ctl_tiling = PLANE_CTL_TILED_YF;
>   		break;
>   	default:
> -		MISSING_CASE(fb->modifier[0]);
> +		MISSING_CASE(fb_modifier);
>   	}
> +	return plane_ctl_tiling;
> +}
>
> -	plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
> -
> -	plane = crtc->primary;
> -	rotation = plane->state->rotation;
> +u32 skl_plane_ctl_rotation(unsigned int rotation)
> +{
> +	u32 plane_ctl_rotation = 0;
>   	switch (rotation) {
> +	case BIT(DRM_ROTATE_0):
> +		break;
>   	case BIT(DRM_ROTATE_90):
> -		plane_ctl |= PLANE_CTL_ROTATE_90;
> +		plane_ctl_rotation = PLANE_CTL_ROTATE_90;
>   		break;
> -
>   	case BIT(DRM_ROTATE_180):
> -		plane_ctl |= PLANE_CTL_ROTATE_180;
> +		plane_ctl_rotation = PLANE_CTL_ROTATE_180;
>   		break;
> -
>   	case BIT(DRM_ROTATE_270):
> -		plane_ctl |= PLANE_CTL_ROTATE_270;
> +		plane_ctl_rotation = PLANE_CTL_ROTATE_270;
>   		break;
> +	default:
> +		MISSING_CASE(rotation);
>   	}
>
> +	return plane_ctl_rotation;
> +}
> +
> +static void skylake_update_primary_plane(struct drm_crtc *crtc,
> +					 struct drm_framebuffer *fb,
> +					 int x, int y)
> +{
> +	struct drm_device *dev = crtc->dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct drm_i915_gem_object *obj;
> +	int pipe = intel_crtc->pipe;
> +	u32 plane_ctl, stride_div, stride;
> +	u32 tile_height, plane_offset, plane_size;
> +	unsigned int rotation;
> +	int x_offset, y_offset;
> +	unsigned long surf_addr;
> +	struct drm_plane *plane;
> +	struct intel_crtc_state *crtc_state = intel_crtc->config;
> +	struct intel_plane_state *plane_state;
> +	int src_x = 0, src_y = 0, src_w = 0, src_h = 0;
> +	int dst_x = 0, dst_y = 0, dst_w = 0, dst_h = 0;
> +	int scaler_id = -1;
> +
> +	plane = crtc->primary;
> +	plane_state = plane ? to_intel_plane_state(crtc->primary->state) : NULL;
> +
> +	if (!intel_crtc->primary_enabled) {
> +		I915_WRITE(PLANE_CTL(pipe, 0), 0);
> +		I915_WRITE(PLANE_SURF(pipe, 0), 0);
> +		POSTING_READ(PLANE_CTL(pipe, 0));
> +		return;
> +	}
> +
> +	plane_ctl = PLANE_CTL_ENABLE |
> +		    PLANE_CTL_PIPE_GAMMA_ENABLE |
> +		    PLANE_CTL_PIPE_CSC_ENABLE;
> +
> +	plane_ctl |= skl_plane_ctl_format(fb->pixel_format);
> +	plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]);
> +	plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
> +
> +	rotation = plane->state->rotation;
> +	plane_ctl |= skl_plane_ctl_rotation(rotation);
> +
>   	obj = intel_fb_obj(fb);
>   	stride_div = intel_fb_stride_alignment(dev, fb->modifier[0],
>   					       fb->pixel_format);
>   	surf_addr = intel_plane_obj_offset(to_intel_plane(plane), obj);
>
> +	if (plane_state && drm_rect_width(&plane_state->src)) {
> +		scaler_id = plane_state->scaler_id;
> +		src_x = plane_state->src.x1 >> 16;
> +		src_y = plane_state->src.y1 >> 16;
> +		src_w = drm_rect_width(&plane_state->src) >> 16;
> +		src_h = drm_rect_height(&plane_state->src) >> 16;
> +		dst_x = plane_state->dst.x1;
> +		dst_y = plane_state->dst.y1;
> +		dst_w = drm_rect_width(&plane_state->dst);
> +		dst_h = drm_rect_height(&plane_state->dst);
> +
> +		WARN_ON(x != src_x || y != src_y);
> +	} else {
> +		src_w = intel_crtc->config->pipe_src_w;
> +		src_h = intel_crtc->config->pipe_src_h;
> +	}
> +
>   	if (intel_rotation_90_or_270(rotation)) {
>   		/* stride = Surface height in tiles */
>   		tile_height = intel_tile_height(dev, fb->bits_per_pixel,
>   						fb->modifier[0]);
>   		stride = DIV_ROUND_UP(fb->height, tile_height);
> -		x_offset = stride * tile_height - y - (plane->state->src_h >> 16);
> +		x_offset = stride * tile_height - y - src_h;
>   		y_offset = x;
> -		plane_size = ((plane->state->src_w >> 16) - 1) << 16 |
> -					((plane->state->src_h >> 16) - 1);
> +		plane_size = (src_w - 1) << 16 | (src_h - 1);
>   	} else {
>   		stride = fb->pitches[0] / stride_div;
>   		x_offset = x;
>   		y_offset = y;
> -		plane_size = ((plane->state->src_h >> 16) - 1) << 16 |
> -			((plane->state->src_w >> 16) - 1);
> +		plane_size = (src_h - 1) << 16 | (src_w - 1);
>   	}
>   	plane_offset = y_offset << 16 | x_offset;
>
>   	I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
> -	I915_WRITE(PLANE_POS(pipe, 0), 0);
>   	I915_WRITE(PLANE_OFFSET(pipe, 0), plane_offset);
>   	I915_WRITE(PLANE_SIZE(pipe, 0), plane_size);
>   	I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
> +
> +	if (scaler_id >= 0) {
> +		uint32_t ps_ctrl = 0;
> +
> +		WARN_ON(!dst_w || !dst_h);
> +		ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(0) |
> +			crtc_state->scaler_state.scalers[scaler_id].mode;
> +		I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
> +		I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
> +		I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (dst_x << 16) | dst_y);
> +		I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id), (dst_w << 16) | dst_h);
> +		I915_WRITE(PLANE_POS(pipe, 0), 0);
> +	} else {
> +		I915_WRITE(PLANE_POS(pipe, 0), (dst_y << 16) | dst_x);
> +	}
> +
>   	I915_WRITE(PLANE_SURF(pipe, 0), surf_addr);
>
>   	POSTING_READ(PLANE_SURF(pipe, 0));
> @@ -4338,6 +4411,7 @@ skl_update_scaler_users(
>   	int *scaler_id;
>   	struct drm_framebuffer *fb;
>   	struct intel_crtc_scaler_state *scaler_state;
> +	unsigned int rotation;
>
>   	if (!intel_crtc || !crtc_state)
>   		return 0;
> @@ -4353,6 +4427,7 @@ skl_update_scaler_users(
>   		dst_w = drm_rect_width(&plane_state->dst);
>   		dst_h = drm_rect_height(&plane_state->dst);
>   		scaler_id = &plane_state->scaler_id;
> +		rotation = plane_state->base.rotation;
>   	} else {
>   		struct drm_display_mode *adjusted_mode =
>   			&crtc_state->base.adjusted_mode;
> @@ -4361,8 +4436,12 @@ skl_update_scaler_users(
>   		dst_w = adjusted_mode->hdisplay;
>   		dst_h = adjusted_mode->vdisplay;
>   		scaler_id = &scaler_state->scaler_id;
> +		rotation = DRM_ROTATE_0;
>   	}
> -	need_scaling = (src_w != dst_w || src_h != dst_h);
> +
> +	need_scaling = intel_rotation_90_or_270(rotation) ?
> +		(src_h != dst_w || src_w != dst_h):
> +		(src_w != dst_w || src_h != dst_h);
>
>   	/*
>   	 * if plane is being disabled or scaler is no more required or force detach
> @@ -12805,6 +12884,36 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
>   	}
>   }
>
> +int
> +skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state)
> +{
> +	int max_scale;
> +	struct drm_device *dev;
> +	struct drm_i915_private *dev_priv;
> +	int crtc_clock, cdclk;
> +
> +	if (!intel_crtc || !crtc_state)
> +		return DRM_PLANE_HELPER_NO_SCALING;
> +
> +	dev = intel_crtc->base.dev;
> +	dev_priv = dev->dev_private;
> +	crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
> +	cdclk = dev_priv->display.get_display_clock_speed(dev);
> +
> +	if (!crtc_clock || !cdclk)
> +		return DRM_PLANE_HELPER_NO_SCALING;
> +
> +	/*
> +	 * skl max scale is lower of:
> +	 *    close to 3 but not 3, -1 is for that purpose
> +	 *            or
> +	 *    cdclk/crtc_clock
> +	 */
> +	max_scale = min((1 << 16) * 3 - 1, (1 << 8) * ((cdclk << 8) / crtc_clock));
> +
> +	return max_scale;
> +}
> +
>   static int
>   intel_check_primary_plane(struct drm_plane *plane,
>   			  struct intel_plane_state *state)
> @@ -12813,23 +12922,31 @@ intel_check_primary_plane(struct drm_plane *plane,
>   	struct drm_i915_private *dev_priv = dev->dev_private;
>   	struct drm_crtc *crtc = state->base.crtc;
>   	struct intel_crtc *intel_crtc;
> +	struct intel_crtc_state *crtc_state;
>   	struct drm_framebuffer *fb = state->base.fb;
>   	struct drm_rect *dest = &state->dst;
>   	struct drm_rect *src = &state->src;
>   	const struct drm_rect *clip = &state->clip;
>   	bool can_position = false;
> +	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
> +	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
>   	int ret;
>
>   	crtc = crtc ? crtc : plane->crtc;
>   	intel_crtc = to_intel_crtc(crtc);
> +	crtc_state = state->base.state ?
> +		intel_atomic_get_crtc_state(state->base.state, intel_crtc) : NULL;
>
> -	if (INTEL_INFO(dev)->gen >= 9)
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		min_scale = 1;
> +		max_scale = skl_max_scale(intel_crtc, crtc_state);
>   		can_position = true;
> +	}
>
>   	ret = drm_plane_helper_check_update(plane, crtc, fb,
>   					    src, dest, clip,
> -					    DRM_PLANE_HELPER_NO_SCALING,
> -					    DRM_PLANE_HELPER_NO_SCALING,
> +					    min_scale,
> +					    max_scale,
>   					    can_position, true,
>   					    &state->visible);
>   	if (ret)
> @@ -12874,6 +12991,13 @@ intel_check_primary_plane(struct drm_plane *plane,
>   			intel_crtc->atomic.update_wm = true;
>   	}
>
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		ret = skl_update_scaler_users(intel_crtc, crtc_state,
> +			to_intel_plane(plane), state, 0);
> +		if (ret)
> +			return ret;
> +	}
> +
>   	return 0;
>   }
>
> @@ -13053,6 +13177,9 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
>
>   	primary->can_scale = false;
>   	primary->max_downscale = 1;
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		primary->can_scale = true;
> +	}
>   	state->scaler_id = -1;
>   	primary->pipe = pipe;
>   	primary->plane = pipe;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 275a4ef..c9bc975 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -288,11 +288,11 @@ struct intel_initial_plane_config {
>   #define SKL_MIN_SRC_W 8
>   #define SKL_MAX_SRC_W 4096
>   #define SKL_MIN_SRC_H 8
> -#define SKL_MAX_SRC_H 2304
> +#define SKL_MAX_SRC_H 4096
>   #define SKL_MIN_DST_W 8
>   #define SKL_MAX_DST_W 4096
>   #define SKL_MIN_DST_H 8
> -#define SKL_MAX_DST_H 2304
> +#define SKL_MAX_DST_H 4096
>
>   struct intel_scaler {
>   	int id;
> @@ -1131,9 +1131,13 @@ void skl_detach_scalers(struct intel_crtc *intel_crtc);
>   int skl_update_scaler_users(struct intel_crtc *intel_crtc,
>   	struct intel_crtc_state *crtc_state, struct intel_plane *intel_plane,
>   	struct intel_plane_state *plane_state, int force_detach);
> +int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state);
>
>   unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
>   				     struct drm_i915_gem_object *obj);
> +u32 skl_plane_ctl_format(uint32_t pixel_format);
> +u32 skl_plane_ctl_tiling(uint64_t fb_modifier);
> +u32 skl_plane_ctl_rotation(unsigned int rotation);
>
>   /* intel_dp.c */
>   void intel_dp_init(struct drm_device *dev, int output_reg, enum port port);
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 0cb3767..2f42777 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -1150,6 +1150,15 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
>   	}
>
>   	intel_plane = to_intel_plane(plane);
> +
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		/* plane scaling and colorkey are mutually exclusive */
> +		if (to_intel_plane_state(plane->state)->scaler_id >= 0) {
> +			DRM_ERROR("colorkey not allowed with scaler\n");
> +			return -EINVAL;
> +		}
> +	}
> +
>   	intel_plane->ckey = *set;
>
>   	/*
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 14/14] drm/i915: skylake sprite plane scaling using shared scalers
  2015-04-15 22:15   ` Chandra Konduru
  2015-04-16  7:42     ` Daniel Vetter
@ 2015-04-16  8:18     ` Jindal, Sonika
  1 sibling, 0 replies; 54+ messages in thread
From: Jindal, Sonika @ 2015-04-16  8:18 UTC (permalink / raw)
  To: Chandra Konduru, intel-gfx; +Cc: daniel.vetter, ander.conselvan.de.oliveira

For v5:

Reviewed-by: Sonika Jindal <sonika.jindal@intel.com> (v5)

Regards,
Sonika

On 4/16/2015 3:45 AM, Chandra Konduru wrote:
> This patch enables skylake sprite plane display scaling using shared
> scalers atomic desgin.
>
> v2:
> -use single copy of scaler limits (Matt)
>
> v3:
> -detaching scalers moved to crtc commit path (Matt)
>
> v4:
> -changes to align with updated scaler structures (Matt, me)
> -keep sprite src rect in 16.16 format (Matt, Daniel)
>
> v5:
> -rebased on top of 90/270 rotation changes (me)
> -Refactored skl_update_plane to reduce its size (Daniel)
>   It is a step towards having a single function covering all planes.
>
> Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
> Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
> Testcase: kms_plane_scaling
> ---
>   drivers/gpu/drm/i915/intel_sprite.c |  125 ++++++++++++++---------------------
>   1 file changed, 48 insertions(+), 77 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 2f42777..497bc1d 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -33,6 +33,7 @@
>   #include <drm/drm_crtc.h>
>   #include <drm/drm_fourcc.h>
>   #include <drm/drm_rect.h>
> +#include <drm/drm_atomic.h>
>   #include <drm/drm_plane_helper.h>
>   #include "intel_drv.h"
>   #include <drm/i915_drm.h>
> @@ -197,80 +198,17 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
>   	u32 tile_height, plane_offset, plane_size;
>   	unsigned int rotation;
>   	int x_offset, y_offset;
> +	struct intel_crtc_state *crtc_state = to_intel_crtc(crtc)->config;
> +	int scaler_id;
>
>   	plane_ctl = PLANE_CTL_ENABLE |
>   		PLANE_CTL_PIPE_CSC_ENABLE;
>
> -	switch (fb->pixel_format) {
> -	case DRM_FORMAT_RGB565:
> -		plane_ctl |= PLANE_CTL_FORMAT_RGB_565;
> -		break;
> -	case DRM_FORMAT_XBGR8888:
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
> -		break;
> -	case DRM_FORMAT_XRGB8888:
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> -		break;
> -	/*
> -	 * XXX: For ARBG/ABGR formats we default to expecting scanout buffers
> -	 * to be already pre-multiplied. We need to add a knob (or a different
> -	 * DRM_FORMAT) for user-space to configure that.
> -	 */
> -	case DRM_FORMAT_ABGR8888:
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 |
> -			     PLANE_CTL_ORDER_RGBX |
> -			     PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> -		break;
> -	case DRM_FORMAT_ARGB8888:
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 |
> -			     PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> -		break;
> -	case DRM_FORMAT_YUYV:
> -		plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV;
> -		break;
> -	case DRM_FORMAT_YVYU:
> -		plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU;
> -		break;
> -	case DRM_FORMAT_UYVY:
> -		plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY;
> -		break;
> -	case DRM_FORMAT_VYUY:
> -		plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
> -		break;
> -	default:
> -		BUG();
> -	}
> -
> -	switch (fb->modifier[0]) {
> -	case DRM_FORMAT_MOD_NONE:
> -		break;
> -	case I915_FORMAT_MOD_X_TILED:
> -		plane_ctl |= PLANE_CTL_TILED_X;
> -		break;
> -	case I915_FORMAT_MOD_Y_TILED:
> -		plane_ctl |= PLANE_CTL_TILED_Y;
> -		break;
> -	case I915_FORMAT_MOD_Yf_TILED:
> -		plane_ctl |= PLANE_CTL_TILED_YF;
> -		break;
> -	default:
> -		MISSING_CASE(fb->modifier[0]);
> -	}
> +	plane_ctl |= skl_plane_ctl_format(fb->pixel_format);
> +	plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]);
>
>   	rotation = drm_plane->state->rotation;
> -	switch (rotation) {
> -	case BIT(DRM_ROTATE_90):
> -		plane_ctl |= PLANE_CTL_ROTATE_90;
> -		break;
> -
> -	case BIT(DRM_ROTATE_180):
> -		plane_ctl |= PLANE_CTL_ROTATE_180;
> -		break;
> -
> -	case BIT(DRM_ROTATE_270):
> -		plane_ctl |= PLANE_CTL_ROTATE_270;
> -		break;
> -	}
> +	plane_ctl |= skl_plane_ctl_rotation(rotation);
>
>   	intel_update_sprite_watermarks(drm_plane, crtc, src_w, src_h,
>   				       pixel_size, true,
> @@ -279,6 +217,8 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
>   	stride_div = intel_fb_stride_alignment(dev, fb->modifier[0],
>   					       fb->pixel_format);
>
> +	scaler_id = to_intel_plane_state(drm_plane->state)->scaler_id;
> +
>   	/* Sizes are 0 based */
>   	src_w--;
>   	src_h--;
> @@ -316,8 +256,27 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
>
>   	I915_WRITE(PLANE_OFFSET(pipe, plane), plane_offset);
>   	I915_WRITE(PLANE_STRIDE(pipe, plane), stride);
> -	I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x);
>   	I915_WRITE(PLANE_SIZE(pipe, plane), plane_size);
> +
> +	/* program plane scaler */
> +	if (scaler_id >= 0) {
> +		uint32_t ps_ctrl = 0;
> +
> +		DRM_DEBUG_KMS("plane = %d PS_PLANE_SEL(plane) = 0x%x\n", plane,
> +			PS_PLANE_SEL(plane));
> +		ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(plane) |
> +			crtc_state->scaler_state.scalers[scaler_id].mode;
> +		I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
> +		I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
> +		I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
> +		I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id),
> +			((crtc_w + 1) << 16)|(crtc_h + 1));
> +
> +		I915_WRITE(PLANE_POS(pipe, plane), 0);
> +	} else {
> +		I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x);
> +	}
> +
>   	I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl);
>   	I915_WRITE(PLANE_SURF(pipe, plane), surf_addr);
>   	POSTING_READ(PLANE_SURF(pipe, plane));
> @@ -894,7 +853,9 @@ static int
>   intel_check_sprite_plane(struct drm_plane *plane,
>   			 struct intel_plane_state *state)
>   {
> +	struct drm_device *dev = plane->dev;
>   	struct intel_crtc *intel_crtc = to_intel_crtc(state->base.crtc);
> +	struct intel_crtc_state *crtc_state;
>   	struct intel_plane *intel_plane = to_intel_plane(plane);
>   	struct drm_framebuffer *fb = state->base.fb;
>   	int crtc_x, crtc_y;
> @@ -906,8 +867,11 @@ intel_check_sprite_plane(struct drm_plane *plane,
>   	int hscale, vscale;
>   	int max_scale, min_scale;
>   	int pixel_size;
> +	int ret;
>
>   	intel_crtc = intel_crtc ? intel_crtc : to_intel_crtc(plane->crtc);
> +	crtc_state = state->base.state ?
> +		intel_atomic_get_crtc_state(state->base.state, intel_crtc) : NULL;
>
>   	if (!fb) {
>   		state->visible = false;
> @@ -934,6 +898,11 @@ intel_check_sprite_plane(struct drm_plane *plane,
>   	max_scale = intel_plane->max_downscale << 16;
>   	min_scale = intel_plane->can_scale ? 1 : (1 << 16);
>
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		min_scale = 1;
> +		max_scale = skl_max_scale(intel_crtc, crtc_state);
> +	}
> +
>   	drm_rect_rotate(src, fb->width << 16, fb->height << 16,
>   			state->base.rotation);
>
> @@ -1029,8 +998,8 @@ intel_check_sprite_plane(struct drm_plane *plane,
>   		width_bytes = ((src_x * pixel_size) & 63) +
>   					src_w * pixel_size;
>
> -		if (src_w > 2048 || src_h > 2048 ||
> -		    width_bytes > 4096 || fb->pitches[0] > 4096) {
> +		if (INTEL_INFO(dev)->gen < 9 && (src_w > 2048 || src_h > 2048 ||
> +		    width_bytes > 4096 || fb->pitches[0] > 4096)) {
>   			DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
>   			return -EINVAL;
>   		}
> @@ -1084,6 +1053,13 @@ finish:
>   		}
>   	}
>
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		ret = skl_update_scaler_users(intel_crtc, crtc_state, intel_plane,
> +			state, 0);
> +		if (ret)
> +			return ret;
> +	}
> +
>   	return 0;
>   }
>
> @@ -1295,12 +1271,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
>   		}
>   		break;
>   	case 9:
> -		/*
> -		 * FIXME: Skylake planes can be scaled (with some restrictions),
> -		 * but this is for another time.
> -		 */
> -		intel_plane->can_scale = false;
> -		intel_plane->max_downscale = 1;
> +		intel_plane->can_scale = true;
>   		intel_plane->update_plane = skl_update_plane;
>   		intel_plane->disable_plane = skl_disable_plane;
>   		state->scaler_id = -1;
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 13/14] drm/i915: skylake primary plane scaling using shared scalers
  2015-04-15 22:14   ` Chandra Konduru
                       ` (2 preceding siblings ...)
  2015-04-16  8:17     ` Jindal, Sonika
@ 2015-04-23 20:20     ` Daniel Vetter
  2015-04-27  5:13       ` Konduru, Chandra
  3 siblings, 1 reply; 54+ messages in thread
From: Daniel Vetter @ 2015-04-23 20:20 UTC (permalink / raw)
  To: Chandra Konduru; +Cc: daniel.vetter, intel-gfx, ander.conselvan.de.oliveira

On Wed, Apr 15, 2015 at 03:14:38PM -0700, Chandra Konduru wrote:
> This patch enables skylake primary plane scaling using shared
> scalers atomic desgin.
> 
> v2:
> -use single copy of scaler limits (Matt)
> 
> v3:
> -move detach_scalers to crtc commit path (Matt)
> -use values in plane_state->src as regular integers (me)
> 
> v4:
> -changes to align with updated scaler structures (Matt, me)
> -keep plane src rect in 16.16 format (Matt, Daniel)
> 
> v5:
> -Rebased on top of 90/270 rotation changes (me)
> -Fixed an issue introduced by 90/270 changes where plane programming
>  is using drm_plane->state rect instead of intel_plane->state rect.
>  This change also required for scaling to work properly. (me)
> -With 90/270, updated limits to cover both portrait and landscape usages (me)
> -Refactored skylake_update_primary_plane to reduce its size (Daniel)
>  Added helper functions for refactoring are comprehended enough to be
>  used for skylake_update_plane (for sprite) too. One stop towards
>  having single function for all planes.
> 
> Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
> Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
> Testcase: kms_plane_scaling

I wanted to pull this in but then spotted an issue. Since this needs one
more round can you perhaps use the older version as a baseline again
(without the refactoring)? Since skl planes aren't converted to universal
planes yet it might be better to wait with refactoring until that's done
actually. Two more comments below.
-Daniel

> ---
>  drivers/gpu/drm/i915/intel_atomic.c  |    5 +-
>  drivers/gpu/drm/i915/intel_display.c |  261 +++++++++++++++++++++++++---------
>  drivers/gpu/drm/i915/intel_drv.h     |    8 +-
>  drivers/gpu/drm/i915/intel_sprite.c  |    9 ++
>  4 files changed, 213 insertions(+), 70 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> index 3c4b7cd..cb6d5f2 100644
> --- a/drivers/gpu/drm/i915/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> @@ -169,7 +169,7 @@ int intel_atomic_commit(struct drm_device *dev,
>  		plane->state->state = NULL;
>  	}
>  
> -	/* swap crtc_state */
> +	/* swap crtc_scaler_state */
>  	for (i = 0; i < dev->mode_config.num_crtc; i++) {
>  		struct drm_crtc *crtc = state->crtcs[i];
>  		if (!crtc) {
> @@ -178,6 +178,9 @@ int intel_atomic_commit(struct drm_device *dev,
>  
>  		to_intel_crtc(crtc)->config->scaler_state =
>  			to_intel_crtc_state(state->crtc_states[i])->scaler_state;
> +
> +		if (INTEL_INFO(dev)->gen >= 9)
> +			skl_detach_scalers(to_intel_crtc(crtc));
>  	}
>  
>  	drm_atomic_helper_commit_planes(dev, state);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 5f7a40f..7f3ae8e 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2960,126 +2960,199 @@ void skl_detach_scalers(struct intel_crtc *intel_crtc)
>  	}
>  }
>  
> -static void skylake_update_primary_plane(struct drm_crtc *crtc,
> -					 struct drm_framebuffer *fb,
> -					 int x, int y)
> +u32 skl_plane_ctl_format(uint32_t pixel_format)
>  {
> -	struct drm_device *dev = crtc->dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -	struct drm_i915_gem_object *obj;
> -	int pipe = intel_crtc->pipe;
> -	u32 plane_ctl, stride_div, stride;
> -	u32 tile_height, plane_offset, plane_size;
> -	unsigned int rotation;
> -	int x_offset, y_offset;
> -	unsigned long surf_addr;
> -	struct drm_plane *plane;
> -
> -	if (!intel_crtc->primary_enabled) {
> -		I915_WRITE(PLANE_CTL(pipe, 0), 0);
> -		I915_WRITE(PLANE_SURF(pipe, 0), 0);
> -		POSTING_READ(PLANE_CTL(pipe, 0));
> -		return;
> -	}
> -
> -	plane_ctl = PLANE_CTL_ENABLE |
> -		    PLANE_CTL_PIPE_GAMMA_ENABLE |
> -		    PLANE_CTL_PIPE_CSC_ENABLE;
> -
> -	switch (fb->pixel_format) {
> +	u32 plane_ctl_format = 0;
> +	switch (pixel_format) {
>  	case DRM_FORMAT_RGB565:
> -		plane_ctl |= PLANE_CTL_FORMAT_RGB_565;
> -		break;
> -	case DRM_FORMAT_XRGB8888:
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> -		break;
> -	case DRM_FORMAT_ARGB8888:
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> -		plane_ctl |= PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> +		plane_ctl_format = PLANE_CTL_FORMAT_RGB_565;
>  		break;
>  	case DRM_FORMAT_XBGR8888:
> -		plane_ctl |= PLANE_CTL_ORDER_RGBX;
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
>  		break;
> +	case DRM_FORMAT_XRGB8888:
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888;
> +		break;
> +	/*
> +	 * XXX: For ARBG/ABGR formats we default to expecting scanout buffers
> +	 * to be already pre-multiplied. We need to add a knob (or a different
> +	 * DRM_FORMAT) for user-space to configure that.
> +	 */
>  	case DRM_FORMAT_ABGR8888:
> -		plane_ctl |= PLANE_CTL_ORDER_RGBX;
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> -		plane_ctl |= PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX |
> +			PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> +		break;
> +	case DRM_FORMAT_ARGB8888:
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 |
> +			PLANE_CTL_ALPHA_SW_PREMULTIPLY;
>  		break;
>  	case DRM_FORMAT_XRGB2101010:
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010;
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_2101010;
>  		break;
>  	case DRM_FORMAT_XBGR2101010:
> -		plane_ctl |= PLANE_CTL_ORDER_RGBX;
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010;
> +		plane_ctl_format = PLANE_CTL_ORDER_RGBX | PLANE_CTL_FORMAT_XRGB_2101010;
> +		break;
> +	case DRM_FORMAT_YUYV:
> +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV;
> +		break;
> +	case DRM_FORMAT_YVYU:
> +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU;
> +		break;
> +	case DRM_FORMAT_UYVY:
> +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY;
> +		break;
> +	case DRM_FORMAT_VYUY:
> +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
>  		break;
>  	default:
>  		BUG();
>  	}
> +	return plane_ctl_format;
> +}
>  
> -	switch (fb->modifier[0]) {
> +u32 skl_plane_ctl_tiling(uint64_t fb_modifier)
> +{
> +	u32 plane_ctl_tiling = 0;
> +	switch (fb_modifier) {
>  	case DRM_FORMAT_MOD_NONE:
>  		break;
>  	case I915_FORMAT_MOD_X_TILED:
> -		plane_ctl |= PLANE_CTL_TILED_X;
> +		plane_ctl_tiling = PLANE_CTL_TILED_X;
>  		break;
>  	case I915_FORMAT_MOD_Y_TILED:
> -		plane_ctl |= PLANE_CTL_TILED_Y;
> +		plane_ctl_tiling = PLANE_CTL_TILED_Y;
>  		break;
>  	case I915_FORMAT_MOD_Yf_TILED:
> -		plane_ctl |= PLANE_CTL_TILED_YF;
> +		plane_ctl_tiling = PLANE_CTL_TILED_YF;
>  		break;
>  	default:
> -		MISSING_CASE(fb->modifier[0]);
> +		MISSING_CASE(fb_modifier);
>  	}
> +	return plane_ctl_tiling;
> +}
>  
> -	plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
> -
> -	plane = crtc->primary;
> -	rotation = plane->state->rotation;
> +u32 skl_plane_ctl_rotation(unsigned int rotation)
> +{
> +	u32 plane_ctl_rotation = 0;
>  	switch (rotation) {
> +	case BIT(DRM_ROTATE_0):
> +		break;
>  	case BIT(DRM_ROTATE_90):
> -		plane_ctl |= PLANE_CTL_ROTATE_90;
> +		plane_ctl_rotation = PLANE_CTL_ROTATE_90;
>  		break;
> -
>  	case BIT(DRM_ROTATE_180):
> -		plane_ctl |= PLANE_CTL_ROTATE_180;
> +		plane_ctl_rotation = PLANE_CTL_ROTATE_180;
>  		break;
> -
>  	case BIT(DRM_ROTATE_270):
> -		plane_ctl |= PLANE_CTL_ROTATE_270;
> +		plane_ctl_rotation = PLANE_CTL_ROTATE_270;
>  		break;
> +	default:
> +		MISSING_CASE(rotation);
>  	}
>  
> +	return plane_ctl_rotation;
> +}
> +
> +static void skylake_update_primary_plane(struct drm_crtc *crtc,
> +					 struct drm_framebuffer *fb,
> +					 int x, int y)
> +{
> +	struct drm_device *dev = crtc->dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct drm_i915_gem_object *obj;
> +	int pipe = intel_crtc->pipe;
> +	u32 plane_ctl, stride_div, stride;
> +	u32 tile_height, plane_offset, plane_size;
> +	unsigned int rotation;
> +	int x_offset, y_offset;
> +	unsigned long surf_addr;
> +	struct drm_plane *plane;
> +	struct intel_crtc_state *crtc_state = intel_crtc->config;
> +	struct intel_plane_state *plane_state;
> +	int src_x = 0, src_y = 0, src_w = 0, src_h = 0;
> +	int dst_x = 0, dst_y = 0, dst_w = 0, dst_h = 0;
> +	int scaler_id = -1;
> +
> +	plane = crtc->primary;
> +	plane_state = plane ? to_intel_plane_state(crtc->primary->state) : NULL;
> +
> +	if (!intel_crtc->primary_enabled) {
> +		I915_WRITE(PLANE_CTL(pipe, 0), 0);
> +		I915_WRITE(PLANE_SURF(pipe, 0), 0);
> +		POSTING_READ(PLANE_CTL(pipe, 0));
> +		return;
> +	}
> +
> +	plane_ctl = PLANE_CTL_ENABLE |
> +		    PLANE_CTL_PIPE_GAMMA_ENABLE |
> +		    PLANE_CTL_PIPE_CSC_ENABLE;
> +
> +	plane_ctl |= skl_plane_ctl_format(fb->pixel_format);
> +	plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]);
> +	plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
> +
> +	rotation = plane->state->rotation;
> +	plane_ctl |= skl_plane_ctl_rotation(rotation);
> +
>  	obj = intel_fb_obj(fb);
>  	stride_div = intel_fb_stride_alignment(dev, fb->modifier[0],
>  					       fb->pixel_format);
>  	surf_addr = intel_plane_obj_offset(to_intel_plane(plane), obj);
>  
> +	if (plane_state && drm_rect_width(&plane_state->src)) {

We discussed this a bit at osts, but can you please explain in a FIXME
comment why this is needed?

> +		scaler_id = plane_state->scaler_id;
> +		src_x = plane_state->src.x1 >> 16;
> +		src_y = plane_state->src.y1 >> 16;
> +		src_w = drm_rect_width(&plane_state->src) >> 16;
> +		src_h = drm_rect_height(&plane_state->src) >> 16;
> +		dst_x = plane_state->dst.x1;
> +		dst_y = plane_state->dst.y1;
> +		dst_w = drm_rect_width(&plane_state->dst);
> +		dst_h = drm_rect_height(&plane_state->dst);
> +
> +		WARN_ON(x != src_x || y != src_y);
> +	} else {
> +		src_w = intel_crtc->config->pipe_src_w;
> +		src_h = intel_crtc->config->pipe_src_h;
> +	}
> +
>  	if (intel_rotation_90_or_270(rotation)) {
>  		/* stride = Surface height in tiles */
>  		tile_height = intel_tile_height(dev, fb->bits_per_pixel,
>  						fb->modifier[0]);
>  		stride = DIV_ROUND_UP(fb->height, tile_height);
> -		x_offset = stride * tile_height - y - (plane->state->src_h >> 16);
> +		x_offset = stride * tile_height - y - src_h;
>  		y_offset = x;
> -		plane_size = ((plane->state->src_w >> 16) - 1) << 16 |
> -					((plane->state->src_h >> 16) - 1);
> +		plane_size = (src_w - 1) << 16 | (src_h - 1);
>  	} else {
>  		stride = fb->pitches[0] / stride_div;
>  		x_offset = x;
>  		y_offset = y;
> -		plane_size = ((plane->state->src_h >> 16) - 1) << 16 |
> -			((plane->state->src_w >> 16) - 1);
> +		plane_size = (src_h - 1) << 16 | (src_w - 1);
>  	}
>  	plane_offset = y_offset << 16 | x_offset;
>  
>  	I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
> -	I915_WRITE(PLANE_POS(pipe, 0), 0);
>  	I915_WRITE(PLANE_OFFSET(pipe, 0), plane_offset);
>  	I915_WRITE(PLANE_SIZE(pipe, 0), plane_size);
>  	I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
> +
> +	if (scaler_id >= 0) {
> +		uint32_t ps_ctrl = 0;
> +
> +		WARN_ON(!dst_w || !dst_h);
> +		ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(0) |
> +			crtc_state->scaler_state.scalers[scaler_id].mode;
> +		I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
> +		I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
> +		I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (dst_x << 16) | dst_y);
> +		I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id), (dst_w << 16) | dst_h);
> +		I915_WRITE(PLANE_POS(pipe, 0), 0);
> +	} else {
> +		I915_WRITE(PLANE_POS(pipe, 0), (dst_y << 16) | dst_x);
> +	}
> +
>  	I915_WRITE(PLANE_SURF(pipe, 0), surf_addr);
>  
>  	POSTING_READ(PLANE_SURF(pipe, 0));
> @@ -4338,6 +4411,7 @@ skl_update_scaler_users(
>  	int *scaler_id;
>  	struct drm_framebuffer *fb;
>  	struct intel_crtc_scaler_state *scaler_state;
> +	unsigned int rotation;
>  
>  	if (!intel_crtc || !crtc_state)
>  		return 0;
> @@ -4353,6 +4427,7 @@ skl_update_scaler_users(
>  		dst_w = drm_rect_width(&plane_state->dst);
>  		dst_h = drm_rect_height(&plane_state->dst);
>  		scaler_id = &plane_state->scaler_id;
> +		rotation = plane_state->base.rotation;
>  	} else {
>  		struct drm_display_mode *adjusted_mode =
>  			&crtc_state->base.adjusted_mode;
> @@ -4361,8 +4436,12 @@ skl_update_scaler_users(
>  		dst_w = adjusted_mode->hdisplay;
>  		dst_h = adjusted_mode->vdisplay;
>  		scaler_id = &scaler_state->scaler_id;
> +		rotation = DRM_ROTATE_0;
>  	}
> -	need_scaling = (src_w != dst_w || src_h != dst_h);
> +
> +	need_scaling = intel_rotation_90_or_270(rotation) ?
> +		(src_h != dst_w || src_w != dst_h):
> +		(src_w != dst_w || src_h != dst_h);
>  
>  	/*
>  	 * if plane is being disabled or scaler is no more required or force detach
> @@ -12805,6 +12884,36 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
>  	}
>  }
>  
> +int
> +skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state)
> +{
> +	int max_scale;
> +	struct drm_device *dev;
> +	struct drm_i915_private *dev_priv;
> +	int crtc_clock, cdclk;
> +
> +	if (!intel_crtc || !crtc_state)
> +		return DRM_PLANE_HELPER_NO_SCALING;
> +
> +	dev = intel_crtc->base.dev;
> +	dev_priv = dev->dev_private;
> +	crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
> +	cdclk = dev_priv->display.get_display_clock_speed(dev);
> +
> +	if (!crtc_clock || !cdclk)
> +		return DRM_PLANE_HELPER_NO_SCALING;
> +
> +	/*
> +	 * skl max scale is lower of:
> +	 *    close to 3 but not 3, -1 is for that purpose
> +	 *            or
> +	 *    cdclk/crtc_clock
> +	 */
> +	max_scale = min((1 << 16) * 3 - 1, (1 << 8) * ((cdclk << 8) / crtc_clock));
> +
> +	return max_scale;
> +}
> +
>  static int
>  intel_check_primary_plane(struct drm_plane *plane,
>  			  struct intel_plane_state *state)
> @@ -12813,23 +12922,31 @@ intel_check_primary_plane(struct drm_plane *plane,
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct drm_crtc *crtc = state->base.crtc;
>  	struct intel_crtc *intel_crtc;
> +	struct intel_crtc_state *crtc_state;
>  	struct drm_framebuffer *fb = state->base.fb;
>  	struct drm_rect *dest = &state->dst;
>  	struct drm_rect *src = &state->src;
>  	const struct drm_rect *clip = &state->clip;
>  	bool can_position = false;
> +	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
> +	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
>  	int ret;
>  
>  	crtc = crtc ? crtc : plane->crtc;
>  	intel_crtc = to_intel_crtc(crtc);
> +	crtc_state = state->base.state ?
> +		intel_atomic_get_crtc_state(state->base.state, intel_crtc) : NULL;
>  
> -	if (INTEL_INFO(dev)->gen >= 9)
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		min_scale = 1;
> +		max_scale = skl_max_scale(intel_crtc, crtc_state);
>  		can_position = true;
> +	}
>  
>  	ret = drm_plane_helper_check_update(plane, crtc, fb,
>  					    src, dest, clip,
> -					    DRM_PLANE_HELPER_NO_SCALING,
> -					    DRM_PLANE_HELPER_NO_SCALING,
> +					    min_scale,
> +					    max_scale,
>  					    can_position, true,
>  					    &state->visible);
>  	if (ret)
> @@ -12874,6 +12991,13 @@ intel_check_primary_plane(struct drm_plane *plane,
>  			intel_crtc->atomic.update_wm = true;
>  	}
>  
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		ret = skl_update_scaler_users(intel_crtc, crtc_state,
> +			to_intel_plane(plane), state, 0);
> +		if (ret)
> +			return ret;
> +	}
> +
>  	return 0;
>  }
>  
> @@ -13053,6 +13177,9 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
>  
>  	primary->can_scale = false;
>  	primary->max_downscale = 1;
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		primary->can_scale = true;
> +	}
>  	state->scaler_id = -1;
>  	primary->pipe = pipe;
>  	primary->plane = pipe;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 275a4ef..c9bc975 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -288,11 +288,11 @@ struct intel_initial_plane_config {
>  #define SKL_MIN_SRC_W 8
>  #define SKL_MAX_SRC_W 4096
>  #define SKL_MIN_SRC_H 8
> -#define SKL_MAX_SRC_H 2304
> +#define SKL_MAX_SRC_H 4096
>  #define SKL_MIN_DST_W 8
>  #define SKL_MAX_DST_W 4096
>  #define SKL_MIN_DST_H 8
> -#define SKL_MAX_DST_H 2304
> +#define SKL_MAX_DST_H 4096
>  
>  struct intel_scaler {
>  	int id;
> @@ -1131,9 +1131,13 @@ void skl_detach_scalers(struct intel_crtc *intel_crtc);
>  int skl_update_scaler_users(struct intel_crtc *intel_crtc,
>  	struct intel_crtc_state *crtc_state, struct intel_plane *intel_plane,
>  	struct intel_plane_state *plane_state, int force_detach);
> +int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state);
>  
>  unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
>  				     struct drm_i915_gem_object *obj);
> +u32 skl_plane_ctl_format(uint32_t pixel_format);
> +u32 skl_plane_ctl_tiling(uint64_t fb_modifier);
> +u32 skl_plane_ctl_rotation(unsigned int rotation);
>  
>  /* intel_dp.c */
>  void intel_dp_init(struct drm_device *dev, int output_reg, enum port port);
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 0cb3767..2f42777 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -1150,6 +1150,15 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
>  	}
>  
>  	intel_plane = to_intel_plane(plane);
> +
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		/* plane scaling and colorkey are mutually exclusive */
> +		if (to_intel_plane_state(plane->state)->scaler_id >= 0) {
> +			DRM_ERROR("colorkey not allowed with scaler\n");
> +			return -EINVAL;

The error path here doesn't correctly release locks. I guess adding some
igt to exercise this path would be good.
-Daniel

> +		}
> +	}
> +
>  	intel_plane->ckey = *set;
>  
>  	/*
> -- 
> 1.7.9.5
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 13/14] drm/i915: skylake primary plane scaling using shared scalers
  2015-04-23 20:20     ` Daniel Vetter
@ 2015-04-27  5:13       ` Konduru, Chandra
  2015-05-04  8:16         ` Daniel Vetter
  0 siblings, 1 reply; 54+ messages in thread
From: Konduru, Chandra @ 2015-04-27  5:13 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Vetter, Daniel, intel-gfx, Conselvan De Oliveira, Ander



> -----Original Message-----
> From: Daniel Vetter [mailto:daniel.vetter@ffwll.ch] On Behalf Of Daniel Vetter
> Sent: Thursday, April 23, 2015 1:20 PM
> To: Konduru, Chandra
> Cc: intel-gfx@lists.freedesktop.org; Vetter, Daniel; Conselvan De Oliveira, Ander
> Subject: Re: [Intel-gfx] [PATCH 13/14] drm/i915: skylake primary plane scaling
> using shared scalers
> 
> On Wed, Apr 15, 2015 at 03:14:38PM -0700, Chandra Konduru wrote:
> > This patch enables skylake primary plane scaling using shared
> > scalers atomic desgin.
> >
> > v2:
> > -use single copy of scaler limits (Matt)
> >
> > v3:
> > -move detach_scalers to crtc commit path (Matt)
> > -use values in plane_state->src as regular integers (me)
> >
> > v4:
> > -changes to align with updated scaler structures (Matt, me)
> > -keep plane src rect in 16.16 format (Matt, Daniel)
> >
> > v5:
> > -Rebased on top of 90/270 rotation changes (me)
> > -Fixed an issue introduced by 90/270 changes where plane programming
> >  is using drm_plane->state rect instead of intel_plane->state rect.
> >  This change also required for scaling to work properly. (me)
> > -With 90/270, updated limits to cover both portrait and landscape usages (me)
> > -Refactored skylake_update_primary_plane to reduce its size (Daniel)
> >  Added helper functions for refactoring are comprehended enough to be
> >  used for skylake_update_plane (for sprite) too. One stop towards
> >  having single function for all planes.
> >
> > Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
> > Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
> > Testcase: kms_plane_scaling
> 
> I wanted to pull this in but then spotted an issue. Since this needs one
> more round can you perhaps use the older version as a baseline again
> (without the refactoring)? Since skl planes aren't converted to universal
> planes yet it might be better to wait with refactoring until that's done
> actually. Two more comments below.
Hi Daniel,
Sorry for delay due to osts/f2f travel.
Per last discussion at osts, you were ok to merge the changes made to
skl update_plane functions to reduce its size. To undo these
changes I have to redo all testing and also have to redo changes
to upcoming nv12 changes.
skl planes are already universal planes, Matt can comment more
on this. But irrespective of whether skl planes universal or not
with below changes, function sizes are more manageable.

Regarding the FIXME and lock issue, will send out updated 
patch shortly. 

-Chandra


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

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

* [PATCH 13/14] drm/i915: skylake primary plane scaling using shared scalers
  2015-04-07 22:28 ` [PATCH 13/14] drm/i915: skylake primary plane scaling " Chandra Konduru
                     ` (3 preceding siblings ...)
  2015-04-15 22:14   ` Chandra Konduru
@ 2015-04-27 20:48   ` Chandra Konduru
  2015-04-29 12:12     ` Jani Nikula
  4 siblings, 1 reply; 54+ messages in thread
From: Chandra Konduru @ 2015-04-27 20:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: daniel.vetter, ander.conselvan.de.oliveira

This patch enables skylake primary plane scaling using shared
scalers atomic desgin.

v2:
-use single copy of scaler limits (Matt)

v3:
-move detach_scalers to crtc commit path (Matt)
-use values in plane_state->src as regular integers (me)

v4:
-changes to align with updated scaler structures (Matt, me)
-keep plane src rect in 16.16 format (Matt, Daniel)

v5:
-Rebased on top of 90/270 rotation changes (me)
-Fixed an issue introduced by 90/270 changes where plane programming
 is using drm_plane->state rect instead of intel_plane->state rect.
 This change also required for scaling to work properly. (me)
-With 90/270, updated limits to cover both portrait and landscape usages (me)
-Refactored skylake_update_primary_plane to reduce its size (Daniel)
 Added helper functions for refactoring are comprehended enough to be
 used for skylake_update_plane (for sprite) too. One stop towards
 having single function for all planes.

v6:
-Added fixme note when checking plane_state->src width in update_plane (Daniel)
-Release lock when failing to colorkey request with active scaler (Daniel)

Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
Reviewed-by: matthew.d.roper@intel.com
Reviewed-by: sonika.jindal@intel.com (v5)
---
 drivers/gpu/drm/i915/intel_atomic.c  |    5 +-
 drivers/gpu/drm/i915/intel_display.c |  266 +++++++++++++++++++++++++---------
 drivers/gpu/drm/i915/intel_drv.h     |    8 +-
 drivers/gpu/drm/i915/intel_sprite.c  |   10 ++
 4 files changed, 219 insertions(+), 70 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 3c4b7cd..cb6d5f2 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -169,7 +169,7 @@ int intel_atomic_commit(struct drm_device *dev,
 		plane->state->state = NULL;
 	}
 
-	/* swap crtc_state */
+	/* swap crtc_scaler_state */
 	for (i = 0; i < dev->mode_config.num_crtc; i++) {
 		struct drm_crtc *crtc = state->crtcs[i];
 		if (!crtc) {
@@ -178,6 +178,9 @@ int intel_atomic_commit(struct drm_device *dev,
 
 		to_intel_crtc(crtc)->config->scaler_state =
 			to_intel_crtc_state(state->crtc_states[i])->scaler_state;
+
+		if (INTEL_INFO(dev)->gen >= 9)
+			skl_detach_scalers(to_intel_crtc(crtc));
 	}
 
 	drm_atomic_helper_commit_planes(dev, state);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 5f7a40f..22799fb 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2960,126 +2960,204 @@ void skl_detach_scalers(struct intel_crtc *intel_crtc)
 	}
 }
 
-static void skylake_update_primary_plane(struct drm_crtc *crtc,
-					 struct drm_framebuffer *fb,
-					 int x, int y)
+u32 skl_plane_ctl_format(uint32_t pixel_format)
 {
-	struct drm_device *dev = crtc->dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct drm_i915_gem_object *obj;
-	int pipe = intel_crtc->pipe;
-	u32 plane_ctl, stride_div, stride;
-	u32 tile_height, plane_offset, plane_size;
-	unsigned int rotation;
-	int x_offset, y_offset;
-	unsigned long surf_addr;
-	struct drm_plane *plane;
-
-	if (!intel_crtc->primary_enabled) {
-		I915_WRITE(PLANE_CTL(pipe, 0), 0);
-		I915_WRITE(PLANE_SURF(pipe, 0), 0);
-		POSTING_READ(PLANE_CTL(pipe, 0));
-		return;
-	}
-
-	plane_ctl = PLANE_CTL_ENABLE |
-		    PLANE_CTL_PIPE_GAMMA_ENABLE |
-		    PLANE_CTL_PIPE_CSC_ENABLE;
-
-	switch (fb->pixel_format) {
+	u32 plane_ctl_format = 0;
+	switch (pixel_format) {
 	case DRM_FORMAT_RGB565:
-		plane_ctl |= PLANE_CTL_FORMAT_RGB_565;
-		break;
-	case DRM_FORMAT_XRGB8888:
-		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
-		break;
-	case DRM_FORMAT_ARGB8888:
-		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
-		plane_ctl |= PLANE_CTL_ALPHA_SW_PREMULTIPLY;
+		plane_ctl_format = PLANE_CTL_FORMAT_RGB_565;
 		break;
 	case DRM_FORMAT_XBGR8888:
-		plane_ctl |= PLANE_CTL_ORDER_RGBX;
-		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
+		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
 		break;
+	case DRM_FORMAT_XRGB8888:
+		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888;
+		break;
+	/*
+	 * XXX: For ARBG/ABGR formats we default to expecting scanout buffers
+	 * to be already pre-multiplied. We need to add a knob (or a different
+	 * DRM_FORMAT) for user-space to configure that.
+	 */
 	case DRM_FORMAT_ABGR8888:
-		plane_ctl |= PLANE_CTL_ORDER_RGBX;
-		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
-		plane_ctl |= PLANE_CTL_ALPHA_SW_PREMULTIPLY;
+		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX |
+			PLANE_CTL_ALPHA_SW_PREMULTIPLY;
+		break;
+	case DRM_FORMAT_ARGB8888:
+		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 |
+			PLANE_CTL_ALPHA_SW_PREMULTIPLY;
 		break;
 	case DRM_FORMAT_XRGB2101010:
-		plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010;
+		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_2101010;
 		break;
 	case DRM_FORMAT_XBGR2101010:
-		plane_ctl |= PLANE_CTL_ORDER_RGBX;
-		plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010;
+		plane_ctl_format = PLANE_CTL_ORDER_RGBX | PLANE_CTL_FORMAT_XRGB_2101010;
+		break;
+	case DRM_FORMAT_YUYV:
+		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV;
+		break;
+	case DRM_FORMAT_YVYU:
+		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU;
+		break;
+	case DRM_FORMAT_UYVY:
+		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY;
+		break;
+	case DRM_FORMAT_VYUY:
+		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
 		break;
 	default:
 		BUG();
 	}
+	return plane_ctl_format;
+}
 
-	switch (fb->modifier[0]) {
+u32 skl_plane_ctl_tiling(uint64_t fb_modifier)
+{
+	u32 plane_ctl_tiling = 0;
+	switch (fb_modifier) {
 	case DRM_FORMAT_MOD_NONE:
 		break;
 	case I915_FORMAT_MOD_X_TILED:
-		plane_ctl |= PLANE_CTL_TILED_X;
+		plane_ctl_tiling = PLANE_CTL_TILED_X;
 		break;
 	case I915_FORMAT_MOD_Y_TILED:
-		plane_ctl |= PLANE_CTL_TILED_Y;
+		plane_ctl_tiling = PLANE_CTL_TILED_Y;
 		break;
 	case I915_FORMAT_MOD_Yf_TILED:
-		plane_ctl |= PLANE_CTL_TILED_YF;
+		plane_ctl_tiling = PLANE_CTL_TILED_YF;
 		break;
 	default:
-		MISSING_CASE(fb->modifier[0]);
+		MISSING_CASE(fb_modifier);
 	}
+	return plane_ctl_tiling;
+}
 
-	plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
-
-	plane = crtc->primary;
-	rotation = plane->state->rotation;
+u32 skl_plane_ctl_rotation(unsigned int rotation)
+{
+	u32 plane_ctl_rotation = 0;
 	switch (rotation) {
+	case BIT(DRM_ROTATE_0):
+		break;
 	case BIT(DRM_ROTATE_90):
-		plane_ctl |= PLANE_CTL_ROTATE_90;
+		plane_ctl_rotation = PLANE_CTL_ROTATE_90;
 		break;
-
 	case BIT(DRM_ROTATE_180):
-		plane_ctl |= PLANE_CTL_ROTATE_180;
+		plane_ctl_rotation = PLANE_CTL_ROTATE_180;
 		break;
-
 	case BIT(DRM_ROTATE_270):
-		plane_ctl |= PLANE_CTL_ROTATE_270;
+		plane_ctl_rotation = PLANE_CTL_ROTATE_270;
 		break;
+	default:
+		MISSING_CASE(rotation);
 	}
 
+	return plane_ctl_rotation;
+}
+
+static void skylake_update_primary_plane(struct drm_crtc *crtc,
+					 struct drm_framebuffer *fb,
+					 int x, int y)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_i915_gem_object *obj;
+	int pipe = intel_crtc->pipe;
+	u32 plane_ctl, stride_div, stride;
+	u32 tile_height, plane_offset, plane_size;
+	unsigned int rotation;
+	int x_offset, y_offset;
+	unsigned long surf_addr;
+	struct drm_plane *plane;
+	struct intel_crtc_state *crtc_state = intel_crtc->config;
+	struct intel_plane_state *plane_state;
+	int src_x = 0, src_y = 0, src_w = 0, src_h = 0;
+	int dst_x = 0, dst_y = 0, dst_w = 0, dst_h = 0;
+	int scaler_id = -1;
+
+	plane = crtc->primary;
+	plane_state = to_intel_plane_state(plane->state);
+
+	if (!intel_crtc->primary_enabled) {
+		I915_WRITE(PLANE_CTL(pipe, 0), 0);
+		I915_WRITE(PLANE_SURF(pipe, 0), 0);
+		POSTING_READ(PLANE_CTL(pipe, 0));
+		return;
+	}
+
+	plane_ctl = PLANE_CTL_ENABLE |
+		    PLANE_CTL_PIPE_GAMMA_ENABLE |
+		    PLANE_CTL_PIPE_CSC_ENABLE;
+
+	plane_ctl |= skl_plane_ctl_format(fb->pixel_format);
+	plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]);
+	plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
+
+	rotation = plane->state->rotation;
+	plane_ctl |= skl_plane_ctl_rotation(rotation);
+
 	obj = intel_fb_obj(fb);
 	stride_div = intel_fb_stride_alignment(dev, fb->modifier[0],
 					       fb->pixel_format);
 	surf_addr = intel_plane_obj_offset(to_intel_plane(plane), obj);
 
+	/*
+	 * FIXME: intel_plane_state->src, dst aren't set when transitional
+	 * update_plane helpers are called from legacy paths.
+	 * Once full atomic crtc is available, below check can be avoided.
+	 */
+	if (drm_rect_width(&plane_state->src)) {
+		scaler_id = plane_state->scaler_id;
+		src_x = plane_state->src.x1 >> 16;
+		src_y = plane_state->src.y1 >> 16;
+		src_w = drm_rect_width(&plane_state->src) >> 16;
+		src_h = drm_rect_height(&plane_state->src) >> 16;
+		dst_x = plane_state->dst.x1;
+		dst_y = plane_state->dst.y1;
+		dst_w = drm_rect_width(&plane_state->dst);
+		dst_h = drm_rect_height(&plane_state->dst);
+
+		WARN_ON(x != src_x || y != src_y);
+	} else {
+		src_w = intel_crtc->config->pipe_src_w;
+		src_h = intel_crtc->config->pipe_src_h;
+	}
+
 	if (intel_rotation_90_or_270(rotation)) {
 		/* stride = Surface height in tiles */
 		tile_height = intel_tile_height(dev, fb->bits_per_pixel,
 						fb->modifier[0]);
 		stride = DIV_ROUND_UP(fb->height, tile_height);
-		x_offset = stride * tile_height - y - (plane->state->src_h >> 16);
+		x_offset = stride * tile_height - y - src_h;
 		y_offset = x;
-		plane_size = ((plane->state->src_w >> 16) - 1) << 16 |
-					((plane->state->src_h >> 16) - 1);
+		plane_size = (src_w - 1) << 16 | (src_h - 1);
 	} else {
 		stride = fb->pitches[0] / stride_div;
 		x_offset = x;
 		y_offset = y;
-		plane_size = ((plane->state->src_h >> 16) - 1) << 16 |
-			((plane->state->src_w >> 16) - 1);
+		plane_size = (src_h - 1) << 16 | (src_w - 1);
 	}
 	plane_offset = y_offset << 16 | x_offset;
 
 	I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
-	I915_WRITE(PLANE_POS(pipe, 0), 0);
 	I915_WRITE(PLANE_OFFSET(pipe, 0), plane_offset);
 	I915_WRITE(PLANE_SIZE(pipe, 0), plane_size);
 	I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
+
+	if (scaler_id >= 0) {
+		uint32_t ps_ctrl = 0;
+
+		WARN_ON(!dst_w || !dst_h);
+		ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(0) |
+			crtc_state->scaler_state.scalers[scaler_id].mode;
+		I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
+		I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
+		I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (dst_x << 16) | dst_y);
+		I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id), (dst_w << 16) | dst_h);
+		I915_WRITE(PLANE_POS(pipe, 0), 0);
+	} else {
+		I915_WRITE(PLANE_POS(pipe, 0), (dst_y << 16) | dst_x);
+	}
+
 	I915_WRITE(PLANE_SURF(pipe, 0), surf_addr);
 
 	POSTING_READ(PLANE_SURF(pipe, 0));
@@ -4338,6 +4416,7 @@ skl_update_scaler_users(
 	int *scaler_id;
 	struct drm_framebuffer *fb;
 	struct intel_crtc_scaler_state *scaler_state;
+	unsigned int rotation;
 
 	if (!intel_crtc || !crtc_state)
 		return 0;
@@ -4353,6 +4432,7 @@ skl_update_scaler_users(
 		dst_w = drm_rect_width(&plane_state->dst);
 		dst_h = drm_rect_height(&plane_state->dst);
 		scaler_id = &plane_state->scaler_id;
+		rotation = plane_state->base.rotation;
 	} else {
 		struct drm_display_mode *adjusted_mode =
 			&crtc_state->base.adjusted_mode;
@@ -4361,8 +4441,12 @@ skl_update_scaler_users(
 		dst_w = adjusted_mode->hdisplay;
 		dst_h = adjusted_mode->vdisplay;
 		scaler_id = &scaler_state->scaler_id;
+		rotation = DRM_ROTATE_0;
 	}
-	need_scaling = (src_w != dst_w || src_h != dst_h);
+
+	need_scaling = intel_rotation_90_or_270(rotation) ?
+		(src_h != dst_w || src_w != dst_h):
+		(src_w != dst_w || src_h != dst_h);
 
 	/*
 	 * if plane is being disabled or scaler is no more required or force detach
@@ -12805,6 +12889,36 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
 	}
 }
 
+int
+skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state)
+{
+	int max_scale;
+	struct drm_device *dev;
+	struct drm_i915_private *dev_priv;
+	int crtc_clock, cdclk;
+
+	if (!intel_crtc || !crtc_state)
+		return DRM_PLANE_HELPER_NO_SCALING;
+
+	dev = intel_crtc->base.dev;
+	dev_priv = dev->dev_private;
+	crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
+	cdclk = dev_priv->display.get_display_clock_speed(dev);
+
+	if (!crtc_clock || !cdclk)
+		return DRM_PLANE_HELPER_NO_SCALING;
+
+	/*
+	 * skl max scale is lower of:
+	 *    close to 3 but not 3, -1 is for that purpose
+	 *            or
+	 *    cdclk/crtc_clock
+	 */
+	max_scale = min((1 << 16) * 3 - 1, (1 << 8) * ((cdclk << 8) / crtc_clock));
+
+	return max_scale;
+}
+
 static int
 intel_check_primary_plane(struct drm_plane *plane,
 			  struct intel_plane_state *state)
@@ -12813,23 +12927,31 @@ intel_check_primary_plane(struct drm_plane *plane,
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_crtc *crtc = state->base.crtc;
 	struct intel_crtc *intel_crtc;
+	struct intel_crtc_state *crtc_state;
 	struct drm_framebuffer *fb = state->base.fb;
 	struct drm_rect *dest = &state->dst;
 	struct drm_rect *src = &state->src;
 	const struct drm_rect *clip = &state->clip;
 	bool can_position = false;
+	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
+	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
 	int ret;
 
 	crtc = crtc ? crtc : plane->crtc;
 	intel_crtc = to_intel_crtc(crtc);
+	crtc_state = state->base.state ?
+		intel_atomic_get_crtc_state(state->base.state, intel_crtc) : NULL;
 
-	if (INTEL_INFO(dev)->gen >= 9)
+	if (INTEL_INFO(dev)->gen >= 9) {
+		min_scale = 1;
+		max_scale = skl_max_scale(intel_crtc, crtc_state);
 		can_position = true;
+	}
 
 	ret = drm_plane_helper_check_update(plane, crtc, fb,
 					    src, dest, clip,
-					    DRM_PLANE_HELPER_NO_SCALING,
-					    DRM_PLANE_HELPER_NO_SCALING,
+					    min_scale,
+					    max_scale,
 					    can_position, true,
 					    &state->visible);
 	if (ret)
@@ -12874,6 +12996,13 @@ intel_check_primary_plane(struct drm_plane *plane,
 			intel_crtc->atomic.update_wm = true;
 	}
 
+	if (INTEL_INFO(dev)->gen >= 9) {
+		ret = skl_update_scaler_users(intel_crtc, crtc_state,
+			to_intel_plane(plane), state, 0);
+		if (ret)
+			return ret;
+	}
+
 	return 0;
 }
 
@@ -13053,6 +13182,9 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
 
 	primary->can_scale = false;
 	primary->max_downscale = 1;
+	if (INTEL_INFO(dev)->gen >= 9) {
+		primary->can_scale = true;
+	}
 	state->scaler_id = -1;
 	primary->pipe = pipe;
 	primary->plane = pipe;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 275a4ef..c9bc975 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -288,11 +288,11 @@ struct intel_initial_plane_config {
 #define SKL_MIN_SRC_W 8
 #define SKL_MAX_SRC_W 4096
 #define SKL_MIN_SRC_H 8
-#define SKL_MAX_SRC_H 2304
+#define SKL_MAX_SRC_H 4096
 #define SKL_MIN_DST_W 8
 #define SKL_MAX_DST_W 4096
 #define SKL_MIN_DST_H 8
-#define SKL_MAX_DST_H 2304
+#define SKL_MAX_DST_H 4096
 
 struct intel_scaler {
 	int id;
@@ -1131,9 +1131,13 @@ void skl_detach_scalers(struct intel_crtc *intel_crtc);
 int skl_update_scaler_users(struct intel_crtc *intel_crtc,
 	struct intel_crtc_state *crtc_state, struct intel_plane *intel_plane,
 	struct intel_plane_state *plane_state, int force_detach);
+int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state);
 
 unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
 				     struct drm_i915_gem_object *obj);
+u32 skl_plane_ctl_format(uint32_t pixel_format);
+u32 skl_plane_ctl_tiling(uint64_t fb_modifier);
+u32 skl_plane_ctl_rotation(unsigned int rotation);
 
 /* intel_dp.c */
 void intel_dp_init(struct drm_device *dev, int output_reg, enum port port);
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 0cb3767..c8e7377 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -1150,6 +1150,16 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
 	}
 
 	intel_plane = to_intel_plane(plane);
+
+	if (INTEL_INFO(dev)->gen >= 9) {
+		/* plane scaling and colorkey are mutually exclusive */
+		if (to_intel_plane_state(plane->state)->scaler_id >= 0) {
+			DRM_ERROR("colorkey not allowed with scaler\n");
+			ret = -EINVAL;
+			goto out_unlock;
+		}
+	}
+
 	intel_plane->ckey = *set;
 
 	/*
-- 
1.7.9.5

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

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

* Re: [PATCH 13/14] drm/i915: skylake primary plane scaling using shared scalers
  2015-04-27 20:48   ` Chandra Konduru
@ 2015-04-29 12:12     ` Jani Nikula
  2015-04-29 16:26       ` Konduru, Chandra
  2015-05-01 16:47       ` Matt Roper
  0 siblings, 2 replies; 54+ messages in thread
From: Jani Nikula @ 2015-04-29 12:12 UTC (permalink / raw)
  To: Chandra Konduru, intel-gfx, Roper, Matthew D
  Cc: daniel.vetter, ander.conselvan.de.oliveira

On Mon, 27 Apr 2015, Chandra Konduru <chandra.konduru@intel.com> wrote:
> This patch enables skylake primary plane scaling using shared
> scalers atomic desgin.
>
> v2:
> -use single copy of scaler limits (Matt)
>
> v3:
> -move detach_scalers to crtc commit path (Matt)
> -use values in plane_state->src as regular integers (me)
>
> v4:
> -changes to align with updated scaler structures (Matt, me)
> -keep plane src rect in 16.16 format (Matt, Daniel)
>
> v5:
> -Rebased on top of 90/270 rotation changes (me)
> -Fixed an issue introduced by 90/270 changes where plane programming
>  is using drm_plane->state rect instead of intel_plane->state rect.
>  This change also required for scaling to work properly. (me)
> -With 90/270, updated limits to cover both portrait and landscape usages (me)
> -Refactored skylake_update_primary_plane to reduce its size (Daniel)
>  Added helper functions for refactoring are comprehended enough to be
>  used for skylake_update_plane (for sprite) too. One stop towards
>  having single function for all planes.
>
> v6:
> -Added fixme note when checking plane_state->src width in update_plane (Daniel)
> -Release lock when failing to colorkey request with active scaler (Daniel)
>
> Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
> Reviewed-by: matthew.d.roper@intel.com

Matt, I never saw an explicit r-b from you for this patch, and there
were also plenty of recent changes. Does your r-b still hold?

Chandra, an earlier version of the patch has Testcase: kms_plane_scaling
but this one doesn't. Does that test now do what Daniel requested in
[1]?

BR,
Jani.


[1] http://mid.gmane.org/20150413181245.GC6092@phenom.ffwll.local

> Reviewed-by: sonika.jindal@intel.com (v5)
> ---
>  drivers/gpu/drm/i915/intel_atomic.c  |    5 +-
>  drivers/gpu/drm/i915/intel_display.c |  266 +++++++++++++++++++++++++---------
>  drivers/gpu/drm/i915/intel_drv.h     |    8 +-
>  drivers/gpu/drm/i915/intel_sprite.c  |   10 ++
>  4 files changed, 219 insertions(+), 70 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> index 3c4b7cd..cb6d5f2 100644
> --- a/drivers/gpu/drm/i915/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> @@ -169,7 +169,7 @@ int intel_atomic_commit(struct drm_device *dev,
>  		plane->state->state = NULL;
>  	}
>  
> -	/* swap crtc_state */
> +	/* swap crtc_scaler_state */
>  	for (i = 0; i < dev->mode_config.num_crtc; i++) {
>  		struct drm_crtc *crtc = state->crtcs[i];
>  		if (!crtc) {
> @@ -178,6 +178,9 @@ int intel_atomic_commit(struct drm_device *dev,
>  
>  		to_intel_crtc(crtc)->config->scaler_state =
>  			to_intel_crtc_state(state->crtc_states[i])->scaler_state;
> +
> +		if (INTEL_INFO(dev)->gen >= 9)
> +			skl_detach_scalers(to_intel_crtc(crtc));
>  	}
>  
>  	drm_atomic_helper_commit_planes(dev, state);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 5f7a40f..22799fb 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2960,126 +2960,204 @@ void skl_detach_scalers(struct intel_crtc *intel_crtc)
>  	}
>  }
>  
> -static void skylake_update_primary_plane(struct drm_crtc *crtc,
> -					 struct drm_framebuffer *fb,
> -					 int x, int y)
> +u32 skl_plane_ctl_format(uint32_t pixel_format)
>  {
> -	struct drm_device *dev = crtc->dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -	struct drm_i915_gem_object *obj;
> -	int pipe = intel_crtc->pipe;
> -	u32 plane_ctl, stride_div, stride;
> -	u32 tile_height, plane_offset, plane_size;
> -	unsigned int rotation;
> -	int x_offset, y_offset;
> -	unsigned long surf_addr;
> -	struct drm_plane *plane;
> -
> -	if (!intel_crtc->primary_enabled) {
> -		I915_WRITE(PLANE_CTL(pipe, 0), 0);
> -		I915_WRITE(PLANE_SURF(pipe, 0), 0);
> -		POSTING_READ(PLANE_CTL(pipe, 0));
> -		return;
> -	}
> -
> -	plane_ctl = PLANE_CTL_ENABLE |
> -		    PLANE_CTL_PIPE_GAMMA_ENABLE |
> -		    PLANE_CTL_PIPE_CSC_ENABLE;
> -
> -	switch (fb->pixel_format) {
> +	u32 plane_ctl_format = 0;
> +	switch (pixel_format) {
>  	case DRM_FORMAT_RGB565:
> -		plane_ctl |= PLANE_CTL_FORMAT_RGB_565;
> -		break;
> -	case DRM_FORMAT_XRGB8888:
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> -		break;
> -	case DRM_FORMAT_ARGB8888:
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> -		plane_ctl |= PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> +		plane_ctl_format = PLANE_CTL_FORMAT_RGB_565;
>  		break;
>  	case DRM_FORMAT_XBGR8888:
> -		plane_ctl |= PLANE_CTL_ORDER_RGBX;
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
>  		break;
> +	case DRM_FORMAT_XRGB8888:
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888;
> +		break;
> +	/*
> +	 * XXX: For ARBG/ABGR formats we default to expecting scanout buffers
> +	 * to be already pre-multiplied. We need to add a knob (or a different
> +	 * DRM_FORMAT) for user-space to configure that.
> +	 */
>  	case DRM_FORMAT_ABGR8888:
> -		plane_ctl |= PLANE_CTL_ORDER_RGBX;
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> -		plane_ctl |= PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX |
> +			PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> +		break;
> +	case DRM_FORMAT_ARGB8888:
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 |
> +			PLANE_CTL_ALPHA_SW_PREMULTIPLY;
>  		break;
>  	case DRM_FORMAT_XRGB2101010:
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010;
> +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_2101010;
>  		break;
>  	case DRM_FORMAT_XBGR2101010:
> -		plane_ctl |= PLANE_CTL_ORDER_RGBX;
> -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010;
> +		plane_ctl_format = PLANE_CTL_ORDER_RGBX | PLANE_CTL_FORMAT_XRGB_2101010;
> +		break;
> +	case DRM_FORMAT_YUYV:
> +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV;
> +		break;
> +	case DRM_FORMAT_YVYU:
> +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU;
> +		break;
> +	case DRM_FORMAT_UYVY:
> +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY;
> +		break;
> +	case DRM_FORMAT_VYUY:
> +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
>  		break;
>  	default:
>  		BUG();
>  	}
> +	return plane_ctl_format;
> +}
>  
> -	switch (fb->modifier[0]) {
> +u32 skl_plane_ctl_tiling(uint64_t fb_modifier)
> +{
> +	u32 plane_ctl_tiling = 0;
> +	switch (fb_modifier) {
>  	case DRM_FORMAT_MOD_NONE:
>  		break;
>  	case I915_FORMAT_MOD_X_TILED:
> -		plane_ctl |= PLANE_CTL_TILED_X;
> +		plane_ctl_tiling = PLANE_CTL_TILED_X;
>  		break;
>  	case I915_FORMAT_MOD_Y_TILED:
> -		plane_ctl |= PLANE_CTL_TILED_Y;
> +		plane_ctl_tiling = PLANE_CTL_TILED_Y;
>  		break;
>  	case I915_FORMAT_MOD_Yf_TILED:
> -		plane_ctl |= PLANE_CTL_TILED_YF;
> +		plane_ctl_tiling = PLANE_CTL_TILED_YF;
>  		break;
>  	default:
> -		MISSING_CASE(fb->modifier[0]);
> +		MISSING_CASE(fb_modifier);
>  	}
> +	return plane_ctl_tiling;
> +}
>  
> -	plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
> -
> -	plane = crtc->primary;
> -	rotation = plane->state->rotation;
> +u32 skl_plane_ctl_rotation(unsigned int rotation)
> +{
> +	u32 plane_ctl_rotation = 0;
>  	switch (rotation) {
> +	case BIT(DRM_ROTATE_0):
> +		break;
>  	case BIT(DRM_ROTATE_90):
> -		plane_ctl |= PLANE_CTL_ROTATE_90;
> +		plane_ctl_rotation = PLANE_CTL_ROTATE_90;
>  		break;
> -
>  	case BIT(DRM_ROTATE_180):
> -		plane_ctl |= PLANE_CTL_ROTATE_180;
> +		plane_ctl_rotation = PLANE_CTL_ROTATE_180;
>  		break;
> -
>  	case BIT(DRM_ROTATE_270):
> -		plane_ctl |= PLANE_CTL_ROTATE_270;
> +		plane_ctl_rotation = PLANE_CTL_ROTATE_270;
>  		break;
> +	default:
> +		MISSING_CASE(rotation);
>  	}
>  
> +	return plane_ctl_rotation;
> +}
> +
> +static void skylake_update_primary_plane(struct drm_crtc *crtc,
> +					 struct drm_framebuffer *fb,
> +					 int x, int y)
> +{
> +	struct drm_device *dev = crtc->dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct drm_i915_gem_object *obj;
> +	int pipe = intel_crtc->pipe;
> +	u32 plane_ctl, stride_div, stride;
> +	u32 tile_height, plane_offset, plane_size;
> +	unsigned int rotation;
> +	int x_offset, y_offset;
> +	unsigned long surf_addr;
> +	struct drm_plane *plane;
> +	struct intel_crtc_state *crtc_state = intel_crtc->config;
> +	struct intel_plane_state *plane_state;
> +	int src_x = 0, src_y = 0, src_w = 0, src_h = 0;
> +	int dst_x = 0, dst_y = 0, dst_w = 0, dst_h = 0;
> +	int scaler_id = -1;
> +
> +	plane = crtc->primary;
> +	plane_state = to_intel_plane_state(plane->state);
> +
> +	if (!intel_crtc->primary_enabled) {
> +		I915_WRITE(PLANE_CTL(pipe, 0), 0);
> +		I915_WRITE(PLANE_SURF(pipe, 0), 0);
> +		POSTING_READ(PLANE_CTL(pipe, 0));
> +		return;
> +	}
> +
> +	plane_ctl = PLANE_CTL_ENABLE |
> +		    PLANE_CTL_PIPE_GAMMA_ENABLE |
> +		    PLANE_CTL_PIPE_CSC_ENABLE;
> +
> +	plane_ctl |= skl_plane_ctl_format(fb->pixel_format);
> +	plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]);
> +	plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
> +
> +	rotation = plane->state->rotation;
> +	plane_ctl |= skl_plane_ctl_rotation(rotation);
> +
>  	obj = intel_fb_obj(fb);
>  	stride_div = intel_fb_stride_alignment(dev, fb->modifier[0],
>  					       fb->pixel_format);
>  	surf_addr = intel_plane_obj_offset(to_intel_plane(plane), obj);
>  
> +	/*
> +	 * FIXME: intel_plane_state->src, dst aren't set when transitional
> +	 * update_plane helpers are called from legacy paths.
> +	 * Once full atomic crtc is available, below check can be avoided.
> +	 */
> +	if (drm_rect_width(&plane_state->src)) {
> +		scaler_id = plane_state->scaler_id;
> +		src_x = plane_state->src.x1 >> 16;
> +		src_y = plane_state->src.y1 >> 16;
> +		src_w = drm_rect_width(&plane_state->src) >> 16;
> +		src_h = drm_rect_height(&plane_state->src) >> 16;
> +		dst_x = plane_state->dst.x1;
> +		dst_y = plane_state->dst.y1;
> +		dst_w = drm_rect_width(&plane_state->dst);
> +		dst_h = drm_rect_height(&plane_state->dst);
> +
> +		WARN_ON(x != src_x || y != src_y);
> +	} else {
> +		src_w = intel_crtc->config->pipe_src_w;
> +		src_h = intel_crtc->config->pipe_src_h;
> +	}
> +
>  	if (intel_rotation_90_or_270(rotation)) {
>  		/* stride = Surface height in tiles */
>  		tile_height = intel_tile_height(dev, fb->bits_per_pixel,
>  						fb->modifier[0]);
>  		stride = DIV_ROUND_UP(fb->height, tile_height);
> -		x_offset = stride * tile_height - y - (plane->state->src_h >> 16);
> +		x_offset = stride * tile_height - y - src_h;
>  		y_offset = x;
> -		plane_size = ((plane->state->src_w >> 16) - 1) << 16 |
> -					((plane->state->src_h >> 16) - 1);
> +		plane_size = (src_w - 1) << 16 | (src_h - 1);
>  	} else {
>  		stride = fb->pitches[0] / stride_div;
>  		x_offset = x;
>  		y_offset = y;
> -		plane_size = ((plane->state->src_h >> 16) - 1) << 16 |
> -			((plane->state->src_w >> 16) - 1);
> +		plane_size = (src_h - 1) << 16 | (src_w - 1);
>  	}
>  	plane_offset = y_offset << 16 | x_offset;
>  
>  	I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
> -	I915_WRITE(PLANE_POS(pipe, 0), 0);
>  	I915_WRITE(PLANE_OFFSET(pipe, 0), plane_offset);
>  	I915_WRITE(PLANE_SIZE(pipe, 0), plane_size);
>  	I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
> +
> +	if (scaler_id >= 0) {
> +		uint32_t ps_ctrl = 0;
> +
> +		WARN_ON(!dst_w || !dst_h);
> +		ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(0) |
> +			crtc_state->scaler_state.scalers[scaler_id].mode;
> +		I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
> +		I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
> +		I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (dst_x << 16) | dst_y);
> +		I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id), (dst_w << 16) | dst_h);
> +		I915_WRITE(PLANE_POS(pipe, 0), 0);
> +	} else {
> +		I915_WRITE(PLANE_POS(pipe, 0), (dst_y << 16) | dst_x);
> +	}
> +
>  	I915_WRITE(PLANE_SURF(pipe, 0), surf_addr);
>  
>  	POSTING_READ(PLANE_SURF(pipe, 0));
> @@ -4338,6 +4416,7 @@ skl_update_scaler_users(
>  	int *scaler_id;
>  	struct drm_framebuffer *fb;
>  	struct intel_crtc_scaler_state *scaler_state;
> +	unsigned int rotation;
>  
>  	if (!intel_crtc || !crtc_state)
>  		return 0;
> @@ -4353,6 +4432,7 @@ skl_update_scaler_users(
>  		dst_w = drm_rect_width(&plane_state->dst);
>  		dst_h = drm_rect_height(&plane_state->dst);
>  		scaler_id = &plane_state->scaler_id;
> +		rotation = plane_state->base.rotation;
>  	} else {
>  		struct drm_display_mode *adjusted_mode =
>  			&crtc_state->base.adjusted_mode;
> @@ -4361,8 +4441,12 @@ skl_update_scaler_users(
>  		dst_w = adjusted_mode->hdisplay;
>  		dst_h = adjusted_mode->vdisplay;
>  		scaler_id = &scaler_state->scaler_id;
> +		rotation = DRM_ROTATE_0;
>  	}
> -	need_scaling = (src_w != dst_w || src_h != dst_h);
> +
> +	need_scaling = intel_rotation_90_or_270(rotation) ?
> +		(src_h != dst_w || src_w != dst_h):
> +		(src_w != dst_w || src_h != dst_h);
>  
>  	/*
>  	 * if plane is being disabled or scaler is no more required or force detach
> @@ -12805,6 +12889,36 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
>  	}
>  }
>  
> +int
> +skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state)
> +{
> +	int max_scale;
> +	struct drm_device *dev;
> +	struct drm_i915_private *dev_priv;
> +	int crtc_clock, cdclk;
> +
> +	if (!intel_crtc || !crtc_state)
> +		return DRM_PLANE_HELPER_NO_SCALING;
> +
> +	dev = intel_crtc->base.dev;
> +	dev_priv = dev->dev_private;
> +	crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
> +	cdclk = dev_priv->display.get_display_clock_speed(dev);
> +
> +	if (!crtc_clock || !cdclk)
> +		return DRM_PLANE_HELPER_NO_SCALING;
> +
> +	/*
> +	 * skl max scale is lower of:
> +	 *    close to 3 but not 3, -1 is for that purpose
> +	 *            or
> +	 *    cdclk/crtc_clock
> +	 */
> +	max_scale = min((1 << 16) * 3 - 1, (1 << 8) * ((cdclk << 8) / crtc_clock));
> +
> +	return max_scale;
> +}
> +
>  static int
>  intel_check_primary_plane(struct drm_plane *plane,
>  			  struct intel_plane_state *state)
> @@ -12813,23 +12927,31 @@ intel_check_primary_plane(struct drm_plane *plane,
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct drm_crtc *crtc = state->base.crtc;
>  	struct intel_crtc *intel_crtc;
> +	struct intel_crtc_state *crtc_state;
>  	struct drm_framebuffer *fb = state->base.fb;
>  	struct drm_rect *dest = &state->dst;
>  	struct drm_rect *src = &state->src;
>  	const struct drm_rect *clip = &state->clip;
>  	bool can_position = false;
> +	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
> +	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
>  	int ret;
>  
>  	crtc = crtc ? crtc : plane->crtc;
>  	intel_crtc = to_intel_crtc(crtc);
> +	crtc_state = state->base.state ?
> +		intel_atomic_get_crtc_state(state->base.state, intel_crtc) : NULL;
>  
> -	if (INTEL_INFO(dev)->gen >= 9)
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		min_scale = 1;
> +		max_scale = skl_max_scale(intel_crtc, crtc_state);
>  		can_position = true;
> +	}
>  
>  	ret = drm_plane_helper_check_update(plane, crtc, fb,
>  					    src, dest, clip,
> -					    DRM_PLANE_HELPER_NO_SCALING,
> -					    DRM_PLANE_HELPER_NO_SCALING,
> +					    min_scale,
> +					    max_scale,
>  					    can_position, true,
>  					    &state->visible);
>  	if (ret)
> @@ -12874,6 +12996,13 @@ intel_check_primary_plane(struct drm_plane *plane,
>  			intel_crtc->atomic.update_wm = true;
>  	}
>  
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		ret = skl_update_scaler_users(intel_crtc, crtc_state,
> +			to_intel_plane(plane), state, 0);
> +		if (ret)
> +			return ret;
> +	}
> +
>  	return 0;
>  }
>  
> @@ -13053,6 +13182,9 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
>  
>  	primary->can_scale = false;
>  	primary->max_downscale = 1;
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		primary->can_scale = true;
> +	}
>  	state->scaler_id = -1;
>  	primary->pipe = pipe;
>  	primary->plane = pipe;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 275a4ef..c9bc975 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -288,11 +288,11 @@ struct intel_initial_plane_config {
>  #define SKL_MIN_SRC_W 8
>  #define SKL_MAX_SRC_W 4096
>  #define SKL_MIN_SRC_H 8
> -#define SKL_MAX_SRC_H 2304
> +#define SKL_MAX_SRC_H 4096
>  #define SKL_MIN_DST_W 8
>  #define SKL_MAX_DST_W 4096
>  #define SKL_MIN_DST_H 8
> -#define SKL_MAX_DST_H 2304
> +#define SKL_MAX_DST_H 4096
>  
>  struct intel_scaler {
>  	int id;
> @@ -1131,9 +1131,13 @@ void skl_detach_scalers(struct intel_crtc *intel_crtc);
>  int skl_update_scaler_users(struct intel_crtc *intel_crtc,
>  	struct intel_crtc_state *crtc_state, struct intel_plane *intel_plane,
>  	struct intel_plane_state *plane_state, int force_detach);
> +int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state);
>  
>  unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
>  				     struct drm_i915_gem_object *obj);
> +u32 skl_plane_ctl_format(uint32_t pixel_format);
> +u32 skl_plane_ctl_tiling(uint64_t fb_modifier);
> +u32 skl_plane_ctl_rotation(unsigned int rotation);
>  
>  /* intel_dp.c */
>  void intel_dp_init(struct drm_device *dev, int output_reg, enum port port);
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 0cb3767..c8e7377 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -1150,6 +1150,16 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
>  	}
>  
>  	intel_plane = to_intel_plane(plane);
> +
> +	if (INTEL_INFO(dev)->gen >= 9) {
> +		/* plane scaling and colorkey are mutually exclusive */
> +		if (to_intel_plane_state(plane->state)->scaler_id >= 0) {
> +			DRM_ERROR("colorkey not allowed with scaler\n");
> +			ret = -EINVAL;
> +			goto out_unlock;
> +		}
> +	}
> +
>  	intel_plane->ckey = *set;
>  
>  	/*
> -- 
> 1.7.9.5
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 13/14] drm/i915: skylake primary plane scaling using shared scalers
  2015-04-29 12:12     ` Jani Nikula
@ 2015-04-29 16:26       ` Konduru, Chandra
  2015-05-01 16:47       ` Matt Roper
  1 sibling, 0 replies; 54+ messages in thread
From: Konduru, Chandra @ 2015-04-29 16:26 UTC (permalink / raw)
  To: Jani Nikula, intel-gfx, Roper, Matthew D
  Cc: Vetter, Daniel, Conselvan De Oliveira, Ander


> -----Original Message-----
> From: Jani Nikula [mailto:jani.nikula@linux.intel.com]
> Sent: Wednesday, April 29, 2015 5:13 AM
> To: Konduru, Chandra; intel-gfx@lists.freedesktop.org; Roper, Matthew D
> Cc: Vetter, Daniel; Conselvan De Oliveira, Ander
> Subject: Re: [Intel-gfx] [PATCH 13/14] drm/i915: skylake primary plane scaling
> using shared scalers
> 
> On Mon, 27 Apr 2015, Chandra Konduru <chandra.konduru@intel.com> wrote:
> > This patch enables skylake primary plane scaling using shared scalers
> > atomic desgin.
> >
> > v2:
> > -use single copy of scaler limits (Matt)
> >
> > v3:
> > -move detach_scalers to crtc commit path (Matt) -use values in
> > plane_state->src as regular integers (me)
> >
> > v4:
> > -changes to align with updated scaler structures (Matt, me) -keep
> > plane src rect in 16.16 format (Matt, Daniel)
> >
> > v5:
> > -Rebased on top of 90/270 rotation changes (me) -Fixed an issue
> > introduced by 90/270 changes where plane programming  is using
> > drm_plane->state rect instead of intel_plane->state rect.
> >  This change also required for scaling to work properly. (me) -With
> > 90/270, updated limits to cover both portrait and landscape usages
> > (me) -Refactored skylake_update_primary_plane to reduce its size
> > (Daniel)  Added helper functions for refactoring are comprehended
> > enough to be  used for skylake_update_plane (for sprite) too. One stop
> > towards  having single function for all planes.
> >
> > v6:
> > -Added fixme note when checking plane_state->src width in update_plane
> > (Daniel) -Release lock when failing to colorkey request with active
> > scaler (Daniel)
> >
> > Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
> > Reviewed-by: matthew.d.roper@intel.com
> 
> Matt, I never saw an explicit r-b from you for this patch, and there were also
> plenty of recent changes. Does your r-b still hold?
> 
> Chandra, an earlier version of the patch has Testcase: kms_plane_scaling but
> this one doesn't. Does that test now do what Daniel requested in [1]?
Hi Jani,
Yes, same kms_plane_scaling is applicable. In patch creation, missed to add back the line:
Testcase: kms_plane_scaling
Regarding review, Matt reviewed until v4. 
For v5: changes are related to rebasing for 90/270, and Matt's suggestion was 
to get it reviewed from 90/270 owner (Sonika). Got R-b for v5 changes from her.
For v6- it is adding a comment and addressing lock issue; nothing new added.
I have sent a patch to update kms_plane_scaling but need some minor updates
to address review feedback. I think, that shouldn't block merge of remaining scaler
patches.
> 
> BR,
> Jani.
> 
> 
> [1] http://mid.gmane.org/20150413181245.GC6092@phenom.ffwll.local
> 
> > Reviewed-by: sonika.jindal@intel.com (v5)
> > ---
> >  drivers/gpu/drm/i915/intel_atomic.c  |    5 +-
> >  drivers/gpu/drm/i915/intel_display.c |  266 +++++++++++++++++++++++++----
> -----
> >  drivers/gpu/drm/i915/intel_drv.h     |    8 +-
> >  drivers/gpu/drm/i915/intel_sprite.c  |   10 ++
> >  4 files changed, 219 insertions(+), 70 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_atomic.c
> > b/drivers/gpu/drm/i915/intel_atomic.c
> > index 3c4b7cd..cb6d5f2 100644
> > --- a/drivers/gpu/drm/i915/intel_atomic.c
> > +++ b/drivers/gpu/drm/i915/intel_atomic.c
> > @@ -169,7 +169,7 @@ int intel_atomic_commit(struct drm_device *dev,
> >  		plane->state->state = NULL;
> >  	}
> >
> > -	/* swap crtc_state */
> > +	/* swap crtc_scaler_state */
> >  	for (i = 0; i < dev->mode_config.num_crtc; i++) {
> >  		struct drm_crtc *crtc = state->crtcs[i];
> >  		if (!crtc) {
> > @@ -178,6 +178,9 @@ int intel_atomic_commit(struct drm_device *dev,
> >
> >  		to_intel_crtc(crtc)->config->scaler_state =
> >  			to_intel_crtc_state(state->crtc_states[i])->scaler_state;
> > +
> > +		if (INTEL_INFO(dev)->gen >= 9)
> > +			skl_detach_scalers(to_intel_crtc(crtc));
> >  	}
> >
> >  	drm_atomic_helper_commit_planes(dev, state); diff --git
> > a/drivers/gpu/drm/i915/intel_display.c
> > b/drivers/gpu/drm/i915/intel_display.c
> > index 5f7a40f..22799fb 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -2960,126 +2960,204 @@ void skl_detach_scalers(struct intel_crtc
> *intel_crtc)
> >  	}
> >  }
> >
> > -static void skylake_update_primary_plane(struct drm_crtc *crtc,
> > -					 struct drm_framebuffer *fb,
> > -					 int x, int y)
> > +u32 skl_plane_ctl_format(uint32_t pixel_format)
> >  {
> > -	struct drm_device *dev = crtc->dev;
> > -	struct drm_i915_private *dev_priv = dev->dev_private;
> > -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > -	struct drm_i915_gem_object *obj;
> > -	int pipe = intel_crtc->pipe;
> > -	u32 plane_ctl, stride_div, stride;
> > -	u32 tile_height, plane_offset, plane_size;
> > -	unsigned int rotation;
> > -	int x_offset, y_offset;
> > -	unsigned long surf_addr;
> > -	struct drm_plane *plane;
> > -
> > -	if (!intel_crtc->primary_enabled) {
> > -		I915_WRITE(PLANE_CTL(pipe, 0), 0);
> > -		I915_WRITE(PLANE_SURF(pipe, 0), 0);
> > -		POSTING_READ(PLANE_CTL(pipe, 0));
> > -		return;
> > -	}
> > -
> > -	plane_ctl = PLANE_CTL_ENABLE |
> > -		    PLANE_CTL_PIPE_GAMMA_ENABLE |
> > -		    PLANE_CTL_PIPE_CSC_ENABLE;
> > -
> > -	switch (fb->pixel_format) {
> > +	u32 plane_ctl_format = 0;
> > +	switch (pixel_format) {
> >  	case DRM_FORMAT_RGB565:
> > -		plane_ctl |= PLANE_CTL_FORMAT_RGB_565;
> > -		break;
> > -	case DRM_FORMAT_XRGB8888:
> > -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> > -		break;
> > -	case DRM_FORMAT_ARGB8888:
> > -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> > -		plane_ctl |= PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> > +		plane_ctl_format = PLANE_CTL_FORMAT_RGB_565;
> >  		break;
> >  	case DRM_FORMAT_XBGR8888:
> > -		plane_ctl |= PLANE_CTL_ORDER_RGBX;
> > -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> > +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 |
> > +PLANE_CTL_ORDER_RGBX;
> >  		break;
> > +	case DRM_FORMAT_XRGB8888:
> > +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888;
> > +		break;
> > +	/*
> > +	 * XXX: For ARBG/ABGR formats we default to expecting scanout buffers
> > +	 * to be already pre-multiplied. We need to add a knob (or a different
> > +	 * DRM_FORMAT) for user-space to configure that.
> > +	 */
> >  	case DRM_FORMAT_ABGR8888:
> > -		plane_ctl |= PLANE_CTL_ORDER_RGBX;
> > -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> > -		plane_ctl |= PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> > +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 |
> PLANE_CTL_ORDER_RGBX |
> > +			PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> > +		break;
> > +	case DRM_FORMAT_ARGB8888:
> > +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 |
> > +			PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> >  		break;
> >  	case DRM_FORMAT_XRGB2101010:
> > -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010;
> > +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_2101010;
> >  		break;
> >  	case DRM_FORMAT_XBGR2101010:
> > -		plane_ctl |= PLANE_CTL_ORDER_RGBX;
> > -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010;
> > +		plane_ctl_format = PLANE_CTL_ORDER_RGBX |
> PLANE_CTL_FORMAT_XRGB_2101010;
> > +		break;
> > +	case DRM_FORMAT_YUYV:
> > +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 |
> PLANE_CTL_YUV422_YUYV;
> > +		break;
> > +	case DRM_FORMAT_YVYU:
> > +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 |
> PLANE_CTL_YUV422_YVYU;
> > +		break;
> > +	case DRM_FORMAT_UYVY:
> > +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 |
> PLANE_CTL_YUV422_UYVY;
> > +		break;
> > +	case DRM_FORMAT_VYUY:
> > +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 |
> PLANE_CTL_YUV422_VYUY;
> >  		break;
> >  	default:
> >  		BUG();
> >  	}
> > +	return plane_ctl_format;
> > +}
> >
> > -	switch (fb->modifier[0]) {
> > +u32 skl_plane_ctl_tiling(uint64_t fb_modifier) {
> > +	u32 plane_ctl_tiling = 0;
> > +	switch (fb_modifier) {
> >  	case DRM_FORMAT_MOD_NONE:
> >  		break;
> >  	case I915_FORMAT_MOD_X_TILED:
> > -		plane_ctl |= PLANE_CTL_TILED_X;
> > +		plane_ctl_tiling = PLANE_CTL_TILED_X;
> >  		break;
> >  	case I915_FORMAT_MOD_Y_TILED:
> > -		plane_ctl |= PLANE_CTL_TILED_Y;
> > +		plane_ctl_tiling = PLANE_CTL_TILED_Y;
> >  		break;
> >  	case I915_FORMAT_MOD_Yf_TILED:
> > -		plane_ctl |= PLANE_CTL_TILED_YF;
> > +		plane_ctl_tiling = PLANE_CTL_TILED_YF;
> >  		break;
> >  	default:
> > -		MISSING_CASE(fb->modifier[0]);
> > +		MISSING_CASE(fb_modifier);
> >  	}
> > +	return plane_ctl_tiling;
> > +}
> >
> > -	plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
> > -
> > -	plane = crtc->primary;
> > -	rotation = plane->state->rotation;
> > +u32 skl_plane_ctl_rotation(unsigned int rotation) {
> > +	u32 plane_ctl_rotation = 0;
> >  	switch (rotation) {
> > +	case BIT(DRM_ROTATE_0):
> > +		break;
> >  	case BIT(DRM_ROTATE_90):
> > -		plane_ctl |= PLANE_CTL_ROTATE_90;
> > +		plane_ctl_rotation = PLANE_CTL_ROTATE_90;
> >  		break;
> > -
> >  	case BIT(DRM_ROTATE_180):
> > -		plane_ctl |= PLANE_CTL_ROTATE_180;
> > +		plane_ctl_rotation = PLANE_CTL_ROTATE_180;
> >  		break;
> > -
> >  	case BIT(DRM_ROTATE_270):
> > -		plane_ctl |= PLANE_CTL_ROTATE_270;
> > +		plane_ctl_rotation = PLANE_CTL_ROTATE_270;
> >  		break;
> > +	default:
> > +		MISSING_CASE(rotation);
> >  	}
> >
> > +	return plane_ctl_rotation;
> > +}
> > +
> > +static void skylake_update_primary_plane(struct drm_crtc *crtc,
> > +					 struct drm_framebuffer *fb,
> > +					 int x, int y)
> > +{
> > +	struct drm_device *dev = crtc->dev;
> > +	struct drm_i915_private *dev_priv = dev->dev_private;
> > +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > +	struct drm_i915_gem_object *obj;
> > +	int pipe = intel_crtc->pipe;
> > +	u32 plane_ctl, stride_div, stride;
> > +	u32 tile_height, plane_offset, plane_size;
> > +	unsigned int rotation;
> > +	int x_offset, y_offset;
> > +	unsigned long surf_addr;
> > +	struct drm_plane *plane;
> > +	struct intel_crtc_state *crtc_state = intel_crtc->config;
> > +	struct intel_plane_state *plane_state;
> > +	int src_x = 0, src_y = 0, src_w = 0, src_h = 0;
> > +	int dst_x = 0, dst_y = 0, dst_w = 0, dst_h = 0;
> > +	int scaler_id = -1;
> > +
> > +	plane = crtc->primary;
> > +	plane_state = to_intel_plane_state(plane->state);
> > +
> > +	if (!intel_crtc->primary_enabled) {
> > +		I915_WRITE(PLANE_CTL(pipe, 0), 0);
> > +		I915_WRITE(PLANE_SURF(pipe, 0), 0);
> > +		POSTING_READ(PLANE_CTL(pipe, 0));
> > +		return;
> > +	}
> > +
> > +	plane_ctl = PLANE_CTL_ENABLE |
> > +		    PLANE_CTL_PIPE_GAMMA_ENABLE |
> > +		    PLANE_CTL_PIPE_CSC_ENABLE;
> > +
> > +	plane_ctl |= skl_plane_ctl_format(fb->pixel_format);
> > +	plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]);
> > +	plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
> > +
> > +	rotation = plane->state->rotation;
> > +	plane_ctl |= skl_plane_ctl_rotation(rotation);
> > +
> >  	obj = intel_fb_obj(fb);
> >  	stride_div = intel_fb_stride_alignment(dev, fb->modifier[0],
> >  					       fb->pixel_format);
> >  	surf_addr = intel_plane_obj_offset(to_intel_plane(plane), obj);
> >
> > +	/*
> > +	 * FIXME: intel_plane_state->src, dst aren't set when transitional
> > +	 * update_plane helpers are called from legacy paths.
> > +	 * Once full atomic crtc is available, below check can be avoided.
> > +	 */
> > +	if (drm_rect_width(&plane_state->src)) {
> > +		scaler_id = plane_state->scaler_id;
> > +		src_x = plane_state->src.x1 >> 16;
> > +		src_y = plane_state->src.y1 >> 16;
> > +		src_w = drm_rect_width(&plane_state->src) >> 16;
> > +		src_h = drm_rect_height(&plane_state->src) >> 16;
> > +		dst_x = plane_state->dst.x1;
> > +		dst_y = plane_state->dst.y1;
> > +		dst_w = drm_rect_width(&plane_state->dst);
> > +		dst_h = drm_rect_height(&plane_state->dst);
> > +
> > +		WARN_ON(x != src_x || y != src_y);
> > +	} else {
> > +		src_w = intel_crtc->config->pipe_src_w;
> > +		src_h = intel_crtc->config->pipe_src_h;
> > +	}
> > +
> >  	if (intel_rotation_90_or_270(rotation)) {
> >  		/* stride = Surface height in tiles */
> >  		tile_height = intel_tile_height(dev, fb->bits_per_pixel,
> >  						fb->modifier[0]);
> >  		stride = DIV_ROUND_UP(fb->height, tile_height);
> > -		x_offset = stride * tile_height - y - (plane->state->src_h >> 16);
> > +		x_offset = stride * tile_height - y - src_h;
> >  		y_offset = x;
> > -		plane_size = ((plane->state->src_w >> 16) - 1) << 16 |
> > -					((plane->state->src_h >> 16) - 1);
> > +		plane_size = (src_w - 1) << 16 | (src_h - 1);
> >  	} else {
> >  		stride = fb->pitches[0] / stride_div;
> >  		x_offset = x;
> >  		y_offset = y;
> > -		plane_size = ((plane->state->src_h >> 16) - 1) << 16 |
> > -			((plane->state->src_w >> 16) - 1);
> > +		plane_size = (src_h - 1) << 16 | (src_w - 1);
> >  	}
> >  	plane_offset = y_offset << 16 | x_offset;
> >
> >  	I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
> > -	I915_WRITE(PLANE_POS(pipe, 0), 0);
> >  	I915_WRITE(PLANE_OFFSET(pipe, 0), plane_offset);
> >  	I915_WRITE(PLANE_SIZE(pipe, 0), plane_size);
> >  	I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
> > +
> > +	if (scaler_id >= 0) {
> > +		uint32_t ps_ctrl = 0;
> > +
> > +		WARN_ON(!dst_w || !dst_h);
> > +		ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(0) |
> > +			crtc_state->scaler_state.scalers[scaler_id].mode;
> > +		I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
> > +		I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
> > +		I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (dst_x << 16) |
> dst_y);
> > +		I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id), (dst_w << 16) |
> dst_h);
> > +		I915_WRITE(PLANE_POS(pipe, 0), 0);
> > +	} else {
> > +		I915_WRITE(PLANE_POS(pipe, 0), (dst_y << 16) | dst_x);
> > +	}
> > +
> >  	I915_WRITE(PLANE_SURF(pipe, 0), surf_addr);
> >
> >  	POSTING_READ(PLANE_SURF(pipe, 0));
> > @@ -4338,6 +4416,7 @@ skl_update_scaler_users(
> >  	int *scaler_id;
> >  	struct drm_framebuffer *fb;
> >  	struct intel_crtc_scaler_state *scaler_state;
> > +	unsigned int rotation;
> >
> >  	if (!intel_crtc || !crtc_state)
> >  		return 0;
> > @@ -4353,6 +4432,7 @@ skl_update_scaler_users(
> >  		dst_w = drm_rect_width(&plane_state->dst);
> >  		dst_h = drm_rect_height(&plane_state->dst);
> >  		scaler_id = &plane_state->scaler_id;
> > +		rotation = plane_state->base.rotation;
> >  	} else {
> >  		struct drm_display_mode *adjusted_mode =
> >  			&crtc_state->base.adjusted_mode;
> > @@ -4361,8 +4441,12 @@ skl_update_scaler_users(
> >  		dst_w = adjusted_mode->hdisplay;
> >  		dst_h = adjusted_mode->vdisplay;
> >  		scaler_id = &scaler_state->scaler_id;
> > +		rotation = DRM_ROTATE_0;
> >  	}
> > -	need_scaling = (src_w != dst_w || src_h != dst_h);
> > +
> > +	need_scaling = intel_rotation_90_or_270(rotation) ?
> > +		(src_h != dst_w || src_w != dst_h):
> > +		(src_w != dst_w || src_h != dst_h);
> >
> >  	/*
> >  	 * if plane is being disabled or scaler is no more required or force
> > detach @@ -12805,6 +12889,36 @@ intel_cleanup_plane_fb(struct
> drm_plane *plane,
> >  	}
> >  }
> >
> > +int
> > +skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state
> > +*crtc_state) {
> > +	int max_scale;
> > +	struct drm_device *dev;
> > +	struct drm_i915_private *dev_priv;
> > +	int crtc_clock, cdclk;
> > +
> > +	if (!intel_crtc || !crtc_state)
> > +		return DRM_PLANE_HELPER_NO_SCALING;
> > +
> > +	dev = intel_crtc->base.dev;
> > +	dev_priv = dev->dev_private;
> > +	crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
> > +	cdclk = dev_priv->display.get_display_clock_speed(dev);
> > +
> > +	if (!crtc_clock || !cdclk)
> > +		return DRM_PLANE_HELPER_NO_SCALING;
> > +
> > +	/*
> > +	 * skl max scale is lower of:
> > +	 *    close to 3 but not 3, -1 is for that purpose
> > +	 *            or
> > +	 *    cdclk/crtc_clock
> > +	 */
> > +	max_scale = min((1 << 16) * 3 - 1, (1 << 8) * ((cdclk << 8) /
> > +crtc_clock));
> > +
> > +	return max_scale;
> > +}
> > +
> >  static int
> >  intel_check_primary_plane(struct drm_plane *plane,
> >  			  struct intel_plane_state *state) @@ -12813,23
> +12927,31 @@
> > intel_check_primary_plane(struct drm_plane *plane,
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> >  	struct drm_crtc *crtc = state->base.crtc;
> >  	struct intel_crtc *intel_crtc;
> > +	struct intel_crtc_state *crtc_state;
> >  	struct drm_framebuffer *fb = state->base.fb;
> >  	struct drm_rect *dest = &state->dst;
> >  	struct drm_rect *src = &state->src;
> >  	const struct drm_rect *clip = &state->clip;
> >  	bool can_position = false;
> > +	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
> > +	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
> >  	int ret;
> >
> >  	crtc = crtc ? crtc : plane->crtc;
> >  	intel_crtc = to_intel_crtc(crtc);
> > +	crtc_state = state->base.state ?
> > +		intel_atomic_get_crtc_state(state->base.state, intel_crtc) :
> NULL;
> >
> > -	if (INTEL_INFO(dev)->gen >= 9)
> > +	if (INTEL_INFO(dev)->gen >= 9) {
> > +		min_scale = 1;
> > +		max_scale = skl_max_scale(intel_crtc, crtc_state);
> >  		can_position = true;
> > +	}
> >
> >  	ret = drm_plane_helper_check_update(plane, crtc, fb,
> >  					    src, dest, clip,
> > -					    DRM_PLANE_HELPER_NO_SCALING,
> > -					    DRM_PLANE_HELPER_NO_SCALING,
> > +					    min_scale,
> > +					    max_scale,
> >  					    can_position, true,
> >  					    &state->visible);
> >  	if (ret)
> > @@ -12874,6 +12996,13 @@ intel_check_primary_plane(struct drm_plane
> *plane,
> >  			intel_crtc->atomic.update_wm = true;
> >  	}
> >
> > +	if (INTEL_INFO(dev)->gen >= 9) {
> > +		ret = skl_update_scaler_users(intel_crtc, crtc_state,
> > +			to_intel_plane(plane), state, 0);
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> >  	return 0;
> >  }
> >
> > @@ -13053,6 +13182,9 @@ static struct drm_plane
> > *intel_primary_plane_create(struct drm_device *dev,
> >
> >  	primary->can_scale = false;
> >  	primary->max_downscale = 1;
> > +	if (INTEL_INFO(dev)->gen >= 9) {
> > +		primary->can_scale = true;
> > +	}
> >  	state->scaler_id = -1;
> >  	primary->pipe = pipe;
> >  	primary->plane = pipe;
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h
> > b/drivers/gpu/drm/i915/intel_drv.h
> > index 275a4ef..c9bc975 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -288,11 +288,11 @@ struct intel_initial_plane_config {  #define
> > SKL_MIN_SRC_W 8  #define SKL_MAX_SRC_W 4096  #define SKL_MIN_SRC_H
> 8
> > -#define SKL_MAX_SRC_H 2304
> > +#define SKL_MAX_SRC_H 4096
> >  #define SKL_MIN_DST_W 8
> >  #define SKL_MAX_DST_W 4096
> >  #define SKL_MIN_DST_H 8
> > -#define SKL_MAX_DST_H 2304
> > +#define SKL_MAX_DST_H 4096
> >
> >  struct intel_scaler {
> >  	int id;
> > @@ -1131,9 +1131,13 @@ void skl_detach_scalers(struct intel_crtc
> > *intel_crtc);  int skl_update_scaler_users(struct intel_crtc *intel_crtc,
> >  	struct intel_crtc_state *crtc_state, struct intel_plane *intel_plane,
> >  	struct intel_plane_state *plane_state, int force_detach);
> > +int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state
> > +*crtc_state);
> >
> >  unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
> >  				     struct drm_i915_gem_object *obj);
> > +u32 skl_plane_ctl_format(uint32_t pixel_format);
> > +u32 skl_plane_ctl_tiling(uint64_t fb_modifier);
> > +u32 skl_plane_ctl_rotation(unsigned int rotation);
> >
> >  /* intel_dp.c */
> >  void intel_dp_init(struct drm_device *dev, int output_reg, enum port
> > port); diff --git a/drivers/gpu/drm/i915/intel_sprite.c
> > b/drivers/gpu/drm/i915/intel_sprite.c
> > index 0cb3767..c8e7377 100644
> > --- a/drivers/gpu/drm/i915/intel_sprite.c
> > +++ b/drivers/gpu/drm/i915/intel_sprite.c
> > @@ -1150,6 +1150,16 @@ int intel_sprite_set_colorkey(struct drm_device
> *dev, void *data,
> >  	}
> >
> >  	intel_plane = to_intel_plane(plane);
> > +
> > +	if (INTEL_INFO(dev)->gen >= 9) {
> > +		/* plane scaling and colorkey are mutually exclusive */
> > +		if (to_intel_plane_state(plane->state)->scaler_id >= 0) {
> > +			DRM_ERROR("colorkey not allowed with scaler\n");
> > +			ret = -EINVAL;
> > +			goto out_unlock;
> > +		}
> > +	}
> > +
> >  	intel_plane->ckey = *set;
> >
> >  	/*
> > --
> > 1.7.9.5
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> --
> Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 13/14] drm/i915: skylake primary plane scaling using shared scalers
  2015-04-29 12:12     ` Jani Nikula
  2015-04-29 16:26       ` Konduru, Chandra
@ 2015-05-01 16:47       ` Matt Roper
  1 sibling, 0 replies; 54+ messages in thread
From: Matt Roper @ 2015-05-01 16:47 UTC (permalink / raw)
  To: Jani Nikula; +Cc: ander.conselvan.de.oliveira, daniel.vetter, intel-gfx

On Wed, Apr 29, 2015 at 03:12:58PM +0300, Jani Nikula wrote:
> On Mon, 27 Apr 2015, Chandra Konduru <chandra.konduru@intel.com> wrote:
> > This patch enables skylake primary plane scaling using shared
> > scalers atomic desgin.
> >
> > v2:
> > -use single copy of scaler limits (Matt)
> >
> > v3:
> > -move detach_scalers to crtc commit path (Matt)
> > -use values in plane_state->src as regular integers (me)
> >
> > v4:
> > -changes to align with updated scaler structures (Matt, me)
> > -keep plane src rect in 16.16 format (Matt, Daniel)
> >
> > v5:
> > -Rebased on top of 90/270 rotation changes (me)
> > -Fixed an issue introduced by 90/270 changes where plane programming
> >  is using drm_plane->state rect instead of intel_plane->state rect.
> >  This change also required for scaling to work properly. (me)
> > -With 90/270, updated limits to cover both portrait and landscape usages (me)
> > -Refactored skylake_update_primary_plane to reduce its size (Daniel)
> >  Added helper functions for refactoring are comprehended enough to be
> >  used for skylake_update_plane (for sprite) too. One stop towards
> >  having single function for all planes.
> >
> > v6:
> > -Added fixme note when checking plane_state->src width in update_plane (Daniel)
> > -Release lock when failing to colorkey request with active scaler (Daniel)
> >
> > Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
> > Reviewed-by: matthew.d.roper@intel.com
> 
> Matt, I never saw an explicit r-b from you for this patch, and there
> were also plenty of recent changes. Does your r-b still hold?

Sorry for the slow response; I've been away from email for a few days.

Yeah, I think I gave my r-b on IRC a while back, but suggested that
Sonika also do a review since the merge conflicts were with her code.
It looks like she's given her r-b as well, so I think this is good to
go.

Reviewed-by: Matt Roper <matthew.d.roper@intel.com>

Thanks.


Matt

> Chandra, an earlier version of the patch has Testcase: kms_plane_scaling
> but this one doesn't. Does that test now do what Daniel requested in
> [1]?
> 
> BR,
> Jani.
> 
> 
> [1] http://mid.gmane.org/20150413181245.GC6092@phenom.ffwll.local
> 
> > Reviewed-by: sonika.jindal@intel.com (v5)
> > ---
> >  drivers/gpu/drm/i915/intel_atomic.c  |    5 +-
> >  drivers/gpu/drm/i915/intel_display.c |  266 +++++++++++++++++++++++++---------
> >  drivers/gpu/drm/i915/intel_drv.h     |    8 +-
> >  drivers/gpu/drm/i915/intel_sprite.c  |   10 ++
> >  4 files changed, 219 insertions(+), 70 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> > index 3c4b7cd..cb6d5f2 100644
> > --- a/drivers/gpu/drm/i915/intel_atomic.c
> > +++ b/drivers/gpu/drm/i915/intel_atomic.c
> > @@ -169,7 +169,7 @@ int intel_atomic_commit(struct drm_device *dev,
> >  		plane->state->state = NULL;
> >  	}
> >  
> > -	/* swap crtc_state */
> > +	/* swap crtc_scaler_state */
> >  	for (i = 0; i < dev->mode_config.num_crtc; i++) {
> >  		struct drm_crtc *crtc = state->crtcs[i];
> >  		if (!crtc) {
> > @@ -178,6 +178,9 @@ int intel_atomic_commit(struct drm_device *dev,
> >  
> >  		to_intel_crtc(crtc)->config->scaler_state =
> >  			to_intel_crtc_state(state->crtc_states[i])->scaler_state;
> > +
> > +		if (INTEL_INFO(dev)->gen >= 9)
> > +			skl_detach_scalers(to_intel_crtc(crtc));
> >  	}
> >  
> >  	drm_atomic_helper_commit_planes(dev, state);
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 5f7a40f..22799fb 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -2960,126 +2960,204 @@ void skl_detach_scalers(struct intel_crtc *intel_crtc)
> >  	}
> >  }
> >  
> > -static void skylake_update_primary_plane(struct drm_crtc *crtc,
> > -					 struct drm_framebuffer *fb,
> > -					 int x, int y)
> > +u32 skl_plane_ctl_format(uint32_t pixel_format)
> >  {
> > -	struct drm_device *dev = crtc->dev;
> > -	struct drm_i915_private *dev_priv = dev->dev_private;
> > -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > -	struct drm_i915_gem_object *obj;
> > -	int pipe = intel_crtc->pipe;
> > -	u32 plane_ctl, stride_div, stride;
> > -	u32 tile_height, plane_offset, plane_size;
> > -	unsigned int rotation;
> > -	int x_offset, y_offset;
> > -	unsigned long surf_addr;
> > -	struct drm_plane *plane;
> > -
> > -	if (!intel_crtc->primary_enabled) {
> > -		I915_WRITE(PLANE_CTL(pipe, 0), 0);
> > -		I915_WRITE(PLANE_SURF(pipe, 0), 0);
> > -		POSTING_READ(PLANE_CTL(pipe, 0));
> > -		return;
> > -	}
> > -
> > -	plane_ctl = PLANE_CTL_ENABLE |
> > -		    PLANE_CTL_PIPE_GAMMA_ENABLE |
> > -		    PLANE_CTL_PIPE_CSC_ENABLE;
> > -
> > -	switch (fb->pixel_format) {
> > +	u32 plane_ctl_format = 0;
> > +	switch (pixel_format) {
> >  	case DRM_FORMAT_RGB565:
> > -		plane_ctl |= PLANE_CTL_FORMAT_RGB_565;
> > -		break;
> > -	case DRM_FORMAT_XRGB8888:
> > -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> > -		break;
> > -	case DRM_FORMAT_ARGB8888:
> > -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> > -		plane_ctl |= PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> > +		plane_ctl_format = PLANE_CTL_FORMAT_RGB_565;
> >  		break;
> >  	case DRM_FORMAT_XBGR8888:
> > -		plane_ctl |= PLANE_CTL_ORDER_RGBX;
> > -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> > +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
> >  		break;
> > +	case DRM_FORMAT_XRGB8888:
> > +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888;
> > +		break;
> > +	/*
> > +	 * XXX: For ARBG/ABGR formats we default to expecting scanout buffers
> > +	 * to be already pre-multiplied. We need to add a knob (or a different
> > +	 * DRM_FORMAT) for user-space to configure that.
> > +	 */
> >  	case DRM_FORMAT_ABGR8888:
> > -		plane_ctl |= PLANE_CTL_ORDER_RGBX;
> > -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> > -		plane_ctl |= PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> > +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX |
> > +			PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> > +		break;
> > +	case DRM_FORMAT_ARGB8888:
> > +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 |
> > +			PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> >  		break;
> >  	case DRM_FORMAT_XRGB2101010:
> > -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010;
> > +		plane_ctl_format = PLANE_CTL_FORMAT_XRGB_2101010;
> >  		break;
> >  	case DRM_FORMAT_XBGR2101010:
> > -		plane_ctl |= PLANE_CTL_ORDER_RGBX;
> > -		plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010;
> > +		plane_ctl_format = PLANE_CTL_ORDER_RGBX | PLANE_CTL_FORMAT_XRGB_2101010;
> > +		break;
> > +	case DRM_FORMAT_YUYV:
> > +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV;
> > +		break;
> > +	case DRM_FORMAT_YVYU:
> > +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU;
> > +		break;
> > +	case DRM_FORMAT_UYVY:
> > +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY;
> > +		break;
> > +	case DRM_FORMAT_VYUY:
> > +		plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
> >  		break;
> >  	default:
> >  		BUG();
> >  	}
> > +	return plane_ctl_format;
> > +}
> >  
> > -	switch (fb->modifier[0]) {
> > +u32 skl_plane_ctl_tiling(uint64_t fb_modifier)
> > +{
> > +	u32 plane_ctl_tiling = 0;
> > +	switch (fb_modifier) {
> >  	case DRM_FORMAT_MOD_NONE:
> >  		break;
> >  	case I915_FORMAT_MOD_X_TILED:
> > -		plane_ctl |= PLANE_CTL_TILED_X;
> > +		plane_ctl_tiling = PLANE_CTL_TILED_X;
> >  		break;
> >  	case I915_FORMAT_MOD_Y_TILED:
> > -		plane_ctl |= PLANE_CTL_TILED_Y;
> > +		plane_ctl_tiling = PLANE_CTL_TILED_Y;
> >  		break;
> >  	case I915_FORMAT_MOD_Yf_TILED:
> > -		plane_ctl |= PLANE_CTL_TILED_YF;
> > +		plane_ctl_tiling = PLANE_CTL_TILED_YF;
> >  		break;
> >  	default:
> > -		MISSING_CASE(fb->modifier[0]);
> > +		MISSING_CASE(fb_modifier);
> >  	}
> > +	return plane_ctl_tiling;
> > +}
> >  
> > -	plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
> > -
> > -	plane = crtc->primary;
> > -	rotation = plane->state->rotation;
> > +u32 skl_plane_ctl_rotation(unsigned int rotation)
> > +{
> > +	u32 plane_ctl_rotation = 0;
> >  	switch (rotation) {
> > +	case BIT(DRM_ROTATE_0):
> > +		break;
> >  	case BIT(DRM_ROTATE_90):
> > -		plane_ctl |= PLANE_CTL_ROTATE_90;
> > +		plane_ctl_rotation = PLANE_CTL_ROTATE_90;
> >  		break;
> > -
> >  	case BIT(DRM_ROTATE_180):
> > -		plane_ctl |= PLANE_CTL_ROTATE_180;
> > +		plane_ctl_rotation = PLANE_CTL_ROTATE_180;
> >  		break;
> > -
> >  	case BIT(DRM_ROTATE_270):
> > -		plane_ctl |= PLANE_CTL_ROTATE_270;
> > +		plane_ctl_rotation = PLANE_CTL_ROTATE_270;
> >  		break;
> > +	default:
> > +		MISSING_CASE(rotation);
> >  	}
> >  
> > +	return plane_ctl_rotation;
> > +}
> > +
> > +static void skylake_update_primary_plane(struct drm_crtc *crtc,
> > +					 struct drm_framebuffer *fb,
> > +					 int x, int y)
> > +{
> > +	struct drm_device *dev = crtc->dev;
> > +	struct drm_i915_private *dev_priv = dev->dev_private;
> > +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > +	struct drm_i915_gem_object *obj;
> > +	int pipe = intel_crtc->pipe;
> > +	u32 plane_ctl, stride_div, stride;
> > +	u32 tile_height, plane_offset, plane_size;
> > +	unsigned int rotation;
> > +	int x_offset, y_offset;
> > +	unsigned long surf_addr;
> > +	struct drm_plane *plane;
> > +	struct intel_crtc_state *crtc_state = intel_crtc->config;
> > +	struct intel_plane_state *plane_state;
> > +	int src_x = 0, src_y = 0, src_w = 0, src_h = 0;
> > +	int dst_x = 0, dst_y = 0, dst_w = 0, dst_h = 0;
> > +	int scaler_id = -1;
> > +
> > +	plane = crtc->primary;
> > +	plane_state = to_intel_plane_state(plane->state);
> > +
> > +	if (!intel_crtc->primary_enabled) {
> > +		I915_WRITE(PLANE_CTL(pipe, 0), 0);
> > +		I915_WRITE(PLANE_SURF(pipe, 0), 0);
> > +		POSTING_READ(PLANE_CTL(pipe, 0));
> > +		return;
> > +	}
> > +
> > +	plane_ctl = PLANE_CTL_ENABLE |
> > +		    PLANE_CTL_PIPE_GAMMA_ENABLE |
> > +		    PLANE_CTL_PIPE_CSC_ENABLE;
> > +
> > +	plane_ctl |= skl_plane_ctl_format(fb->pixel_format);
> > +	plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]);
> > +	plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
> > +
> > +	rotation = plane->state->rotation;
> > +	plane_ctl |= skl_plane_ctl_rotation(rotation);
> > +
> >  	obj = intel_fb_obj(fb);
> >  	stride_div = intel_fb_stride_alignment(dev, fb->modifier[0],
> >  					       fb->pixel_format);
> >  	surf_addr = intel_plane_obj_offset(to_intel_plane(plane), obj);
> >  
> > +	/*
> > +	 * FIXME: intel_plane_state->src, dst aren't set when transitional
> > +	 * update_plane helpers are called from legacy paths.
> > +	 * Once full atomic crtc is available, below check can be avoided.
> > +	 */
> > +	if (drm_rect_width(&plane_state->src)) {
> > +		scaler_id = plane_state->scaler_id;
> > +		src_x = plane_state->src.x1 >> 16;
> > +		src_y = plane_state->src.y1 >> 16;
> > +		src_w = drm_rect_width(&plane_state->src) >> 16;
> > +		src_h = drm_rect_height(&plane_state->src) >> 16;
> > +		dst_x = plane_state->dst.x1;
> > +		dst_y = plane_state->dst.y1;
> > +		dst_w = drm_rect_width(&plane_state->dst);
> > +		dst_h = drm_rect_height(&plane_state->dst);
> > +
> > +		WARN_ON(x != src_x || y != src_y);
> > +	} else {
> > +		src_w = intel_crtc->config->pipe_src_w;
> > +		src_h = intel_crtc->config->pipe_src_h;
> > +	}
> > +
> >  	if (intel_rotation_90_or_270(rotation)) {
> >  		/* stride = Surface height in tiles */
> >  		tile_height = intel_tile_height(dev, fb->bits_per_pixel,
> >  						fb->modifier[0]);
> >  		stride = DIV_ROUND_UP(fb->height, tile_height);
> > -		x_offset = stride * tile_height - y - (plane->state->src_h >> 16);
> > +		x_offset = stride * tile_height - y - src_h;
> >  		y_offset = x;
> > -		plane_size = ((plane->state->src_w >> 16) - 1) << 16 |
> > -					((plane->state->src_h >> 16) - 1);
> > +		plane_size = (src_w - 1) << 16 | (src_h - 1);
> >  	} else {
> >  		stride = fb->pitches[0] / stride_div;
> >  		x_offset = x;
> >  		y_offset = y;
> > -		plane_size = ((plane->state->src_h >> 16) - 1) << 16 |
> > -			((plane->state->src_w >> 16) - 1);
> > +		plane_size = (src_h - 1) << 16 | (src_w - 1);
> >  	}
> >  	plane_offset = y_offset << 16 | x_offset;
> >  
> >  	I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
> > -	I915_WRITE(PLANE_POS(pipe, 0), 0);
> >  	I915_WRITE(PLANE_OFFSET(pipe, 0), plane_offset);
> >  	I915_WRITE(PLANE_SIZE(pipe, 0), plane_size);
> >  	I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
> > +
> > +	if (scaler_id >= 0) {
> > +		uint32_t ps_ctrl = 0;
> > +
> > +		WARN_ON(!dst_w || !dst_h);
> > +		ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(0) |
> > +			crtc_state->scaler_state.scalers[scaler_id].mode;
> > +		I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
> > +		I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
> > +		I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (dst_x << 16) | dst_y);
> > +		I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id), (dst_w << 16) | dst_h);
> > +		I915_WRITE(PLANE_POS(pipe, 0), 0);
> > +	} else {
> > +		I915_WRITE(PLANE_POS(pipe, 0), (dst_y << 16) | dst_x);
> > +	}
> > +
> >  	I915_WRITE(PLANE_SURF(pipe, 0), surf_addr);
> >  
> >  	POSTING_READ(PLANE_SURF(pipe, 0));
> > @@ -4338,6 +4416,7 @@ skl_update_scaler_users(
> >  	int *scaler_id;
> >  	struct drm_framebuffer *fb;
> >  	struct intel_crtc_scaler_state *scaler_state;
> > +	unsigned int rotation;
> >  
> >  	if (!intel_crtc || !crtc_state)
> >  		return 0;
> > @@ -4353,6 +4432,7 @@ skl_update_scaler_users(
> >  		dst_w = drm_rect_width(&plane_state->dst);
> >  		dst_h = drm_rect_height(&plane_state->dst);
> >  		scaler_id = &plane_state->scaler_id;
> > +		rotation = plane_state->base.rotation;
> >  	} else {
> >  		struct drm_display_mode *adjusted_mode =
> >  			&crtc_state->base.adjusted_mode;
> > @@ -4361,8 +4441,12 @@ skl_update_scaler_users(
> >  		dst_w = adjusted_mode->hdisplay;
> >  		dst_h = adjusted_mode->vdisplay;
> >  		scaler_id = &scaler_state->scaler_id;
> > +		rotation = DRM_ROTATE_0;
> >  	}
> > -	need_scaling = (src_w != dst_w || src_h != dst_h);
> > +
> > +	need_scaling = intel_rotation_90_or_270(rotation) ?
> > +		(src_h != dst_w || src_w != dst_h):
> > +		(src_w != dst_w || src_h != dst_h);
> >  
> >  	/*
> >  	 * if plane is being disabled or scaler is no more required or force detach
> > @@ -12805,6 +12889,36 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
> >  	}
> >  }
> >  
> > +int
> > +skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state)
> > +{
> > +	int max_scale;
> > +	struct drm_device *dev;
> > +	struct drm_i915_private *dev_priv;
> > +	int crtc_clock, cdclk;
> > +
> > +	if (!intel_crtc || !crtc_state)
> > +		return DRM_PLANE_HELPER_NO_SCALING;
> > +
> > +	dev = intel_crtc->base.dev;
> > +	dev_priv = dev->dev_private;
> > +	crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
> > +	cdclk = dev_priv->display.get_display_clock_speed(dev);
> > +
> > +	if (!crtc_clock || !cdclk)
> > +		return DRM_PLANE_HELPER_NO_SCALING;
> > +
> > +	/*
> > +	 * skl max scale is lower of:
> > +	 *    close to 3 but not 3, -1 is for that purpose
> > +	 *            or
> > +	 *    cdclk/crtc_clock
> > +	 */
> > +	max_scale = min((1 << 16) * 3 - 1, (1 << 8) * ((cdclk << 8) / crtc_clock));
> > +
> > +	return max_scale;
> > +}
> > +
> >  static int
> >  intel_check_primary_plane(struct drm_plane *plane,
> >  			  struct intel_plane_state *state)
> > @@ -12813,23 +12927,31 @@ intel_check_primary_plane(struct drm_plane *plane,
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> >  	struct drm_crtc *crtc = state->base.crtc;
> >  	struct intel_crtc *intel_crtc;
> > +	struct intel_crtc_state *crtc_state;
> >  	struct drm_framebuffer *fb = state->base.fb;
> >  	struct drm_rect *dest = &state->dst;
> >  	struct drm_rect *src = &state->src;
> >  	const struct drm_rect *clip = &state->clip;
> >  	bool can_position = false;
> > +	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
> > +	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
> >  	int ret;
> >  
> >  	crtc = crtc ? crtc : plane->crtc;
> >  	intel_crtc = to_intel_crtc(crtc);
> > +	crtc_state = state->base.state ?
> > +		intel_atomic_get_crtc_state(state->base.state, intel_crtc) : NULL;
> >  
> > -	if (INTEL_INFO(dev)->gen >= 9)
> > +	if (INTEL_INFO(dev)->gen >= 9) {
> > +		min_scale = 1;
> > +		max_scale = skl_max_scale(intel_crtc, crtc_state);
> >  		can_position = true;
> > +	}
> >  
> >  	ret = drm_plane_helper_check_update(plane, crtc, fb,
> >  					    src, dest, clip,
> > -					    DRM_PLANE_HELPER_NO_SCALING,
> > -					    DRM_PLANE_HELPER_NO_SCALING,
> > +					    min_scale,
> > +					    max_scale,
> >  					    can_position, true,
> >  					    &state->visible);
> >  	if (ret)
> > @@ -12874,6 +12996,13 @@ intel_check_primary_plane(struct drm_plane *plane,
> >  			intel_crtc->atomic.update_wm = true;
> >  	}
> >  
> > +	if (INTEL_INFO(dev)->gen >= 9) {
> > +		ret = skl_update_scaler_users(intel_crtc, crtc_state,
> > +			to_intel_plane(plane), state, 0);
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> >  	return 0;
> >  }
> >  
> > @@ -13053,6 +13182,9 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
> >  
> >  	primary->can_scale = false;
> >  	primary->max_downscale = 1;
> > +	if (INTEL_INFO(dev)->gen >= 9) {
> > +		primary->can_scale = true;
> > +	}
> >  	state->scaler_id = -1;
> >  	primary->pipe = pipe;
> >  	primary->plane = pipe;
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index 275a4ef..c9bc975 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -288,11 +288,11 @@ struct intel_initial_plane_config {
> >  #define SKL_MIN_SRC_W 8
> >  #define SKL_MAX_SRC_W 4096
> >  #define SKL_MIN_SRC_H 8
> > -#define SKL_MAX_SRC_H 2304
> > +#define SKL_MAX_SRC_H 4096
> >  #define SKL_MIN_DST_W 8
> >  #define SKL_MAX_DST_W 4096
> >  #define SKL_MIN_DST_H 8
> > -#define SKL_MAX_DST_H 2304
> > +#define SKL_MAX_DST_H 4096
> >  
> >  struct intel_scaler {
> >  	int id;
> > @@ -1131,9 +1131,13 @@ void skl_detach_scalers(struct intel_crtc *intel_crtc);
> >  int skl_update_scaler_users(struct intel_crtc *intel_crtc,
> >  	struct intel_crtc_state *crtc_state, struct intel_plane *intel_plane,
> >  	struct intel_plane_state *plane_state, int force_detach);
> > +int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state);
> >  
> >  unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
> >  				     struct drm_i915_gem_object *obj);
> > +u32 skl_plane_ctl_format(uint32_t pixel_format);
> > +u32 skl_plane_ctl_tiling(uint64_t fb_modifier);
> > +u32 skl_plane_ctl_rotation(unsigned int rotation);
> >  
> >  /* intel_dp.c */
> >  void intel_dp_init(struct drm_device *dev, int output_reg, enum port port);
> > diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> > index 0cb3767..c8e7377 100644
> > --- a/drivers/gpu/drm/i915/intel_sprite.c
> > +++ b/drivers/gpu/drm/i915/intel_sprite.c
> > @@ -1150,6 +1150,16 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
> >  	}
> >  
> >  	intel_plane = to_intel_plane(plane);
> > +
> > +	if (INTEL_INFO(dev)->gen >= 9) {
> > +		/* plane scaling and colorkey are mutually exclusive */
> > +		if (to_intel_plane_state(plane->state)->scaler_id >= 0) {
> > +			DRM_ERROR("colorkey not allowed with scaler\n");
> > +			ret = -EINVAL;
> > +			goto out_unlock;
> > +		}
> > +	}
> > +
> >  	intel_plane->ckey = *set;
> >  
> >  	/*
> > -- 
> > 1.7.9.5
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Jani Nikula, Intel Open Source Technology Center

-- 
Matt Roper
Graphics Software Engineer
IoTG Platform Enabling & Development
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 13/14] drm/i915: skylake primary plane scaling using shared scalers
  2015-04-27  5:13       ` Konduru, Chandra
@ 2015-05-04  8:16         ` Daniel Vetter
  0 siblings, 0 replies; 54+ messages in thread
From: Daniel Vetter @ 2015-05-04  8:16 UTC (permalink / raw)
  To: Konduru, Chandra; +Cc: Vetter, Daniel, intel-gfx, Conselvan De Oliveira, Ander

On Mon, Apr 27, 2015 at 05:13:49AM +0000, Konduru, Chandra wrote:
> 
> 
> > -----Original Message-----
> > From: Daniel Vetter [mailto:daniel.vetter@ffwll.ch] On Behalf Of Daniel Vetter
> > Sent: Thursday, April 23, 2015 1:20 PM
> > To: Konduru, Chandra
> > Cc: intel-gfx@lists.freedesktop.org; Vetter, Daniel; Conselvan De Oliveira, Ander
> > Subject: Re: [Intel-gfx] [PATCH 13/14] drm/i915: skylake primary plane scaling
> > using shared scalers
> > 
> > On Wed, Apr 15, 2015 at 03:14:38PM -0700, Chandra Konduru wrote:
> > > This patch enables skylake primary plane scaling using shared
> > > scalers atomic desgin.
> > >
> > > v2:
> > > -use single copy of scaler limits (Matt)
> > >
> > > v3:
> > > -move detach_scalers to crtc commit path (Matt)
> > > -use values in plane_state->src as regular integers (me)
> > >
> > > v4:
> > > -changes to align with updated scaler structures (Matt, me)
> > > -keep plane src rect in 16.16 format (Matt, Daniel)
> > >
> > > v5:
> > > -Rebased on top of 90/270 rotation changes (me)
> > > -Fixed an issue introduced by 90/270 changes where plane programming
> > >  is using drm_plane->state rect instead of intel_plane->state rect.
> > >  This change also required for scaling to work properly. (me)
> > > -With 90/270, updated limits to cover both portrait and landscape usages (me)
> > > -Refactored skylake_update_primary_plane to reduce its size (Daniel)
> > >  Added helper functions for refactoring are comprehended enough to be
> > >  used for skylake_update_plane (for sprite) too. One stop towards
> > >  having single function for all planes.
> > >
> > > Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
> > > Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
> > > Testcase: kms_plane_scaling
> > 
> > I wanted to pull this in but then spotted an issue. Since this needs one
> > more round can you perhaps use the older version as a baseline again
> > (without the refactoring)? Since skl planes aren't converted to universal
> > planes yet it might be better to wait with refactoring until that's done
> > actually. Two more comments below.
> Hi Daniel,
> Sorry for delay due to osts/f2f travel.
> Per last discussion at osts, you were ok to merge the changes made to
> skl update_plane functions to reduce its size. To undo these
> changes I have to redo all testing and also have to redo changes
> to upcoming nv12 changes.
> skl planes are already universal planes, Matt can comment more
> on this. But irrespective of whether skl planes universal or not
> with below changes, function sizes are more manageable.

Yeah I looked at splitting up the refactoring, but because of the
divergent history of the primary and sprite planes (which converged now in
the hw for skl) it was messier than your patches here. Agreed that this is
the exception which confirms the rule ;-)
> 
> Regarding the FIXME and lock issue, will send out updated 
> patch shortly. 

Thanks, both applied to dinq.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

end of thread, other threads:[~2015-05-04  8:13 UTC | newest]

Thread overview: 54+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-07 22:28 [PATCH 00/14] skylake display scalers Chandra Konduru
2015-04-07 22:28 ` [PATCH 01/14] drm: Adding drm helper function drm_plane_from_index() Chandra Konduru
2015-04-10  0:36   ` Chandra Konduru
2015-04-10  6:59     ` Daniel Vetter
2015-04-10 16:30       ` Konduru, Chandra
2015-04-07 22:28 ` [PATCH 02/14] drm/i915: Register definitions for skylake scalers Chandra Konduru
2015-04-07 22:28 ` [PATCH 03/14] drm/i915: skylake scaler structure definitions Chandra Konduru
2015-04-07 22:28 ` [PATCH 04/14] drm/i915: Initialize plane colorkey to NONE Chandra Konduru
2015-04-07 22:28 ` [PATCH 05/14] drm/i915: Initialize skylake scalers Chandra Konduru
2015-04-07 22:28 ` [PATCH 06/14] drm/i915: Keep sprite plane src rect in 16.16 format Chandra Konduru
2015-04-09 21:50   ` Matt Roper
2015-04-09 22:08     ` Konduru, Chandra
2015-04-09 22:22       ` Matt Roper
2015-04-09 22:27         ` Konduru, Chandra
2015-04-09 23:41   ` Chandra Konduru
2015-04-09 23:57     ` Matt Roper
2015-04-07 22:28 ` [PATCH 07/14] drm/i915: Dump scaler_state too as part of dumping crtc_state Chandra Konduru
2015-04-07 22:28 ` [PATCH 08/14] drm/i915: Preserve scaler state when clearing crtc_state Chandra Konduru
2015-04-07 22:28 ` [PATCH 09/14] drm/i915: setup scalers for crtc_compute_config Chandra Konduru
2015-04-09 21:51   ` Matt Roper
2015-04-09 22:07     ` Konduru, Chandra
2015-04-09 23:42   ` Chandra Konduru
2015-04-07 22:28 ` [PATCH 10/14] drm/i915: Ensure setting up scalers into staged crtc_state Chandra Konduru
2015-04-07 22:28 ` [PATCH 11/14] drm/i915: copy staged scaler state from drm state to crtc->config Chandra Konduru
2015-04-07 22:28 ` [PATCH 12/14] drm/i915: skylake panel fitting using shared scalers Chandra Konduru
2015-04-07 22:28 ` [PATCH 13/14] drm/i915: skylake primary plane scaling " Chandra Konduru
2015-04-09 21:51   ` Matt Roper
2015-04-09 22:14     ` Konduru, Chandra
2015-04-13  9:46       ` Daniel Vetter
2015-04-13 18:12   ` Daniel Vetter
2015-04-13 18:18     ` Konduru, Chandra
2015-04-14  7:00   ` Daniel Vetter
2015-04-15 22:14   ` Chandra Konduru
2015-04-15 23:08     ` Konduru, Chandra
2015-04-16  7:36     ` Daniel Vetter
2015-04-16  8:17     ` Jindal, Sonika
2015-04-23 20:20     ` Daniel Vetter
2015-04-27  5:13       ` Konduru, Chandra
2015-05-04  8:16         ` Daniel Vetter
2015-04-27 20:48   ` Chandra Konduru
2015-04-29 12:12     ` Jani Nikula
2015-04-29 16:26       ` Konduru, Chandra
2015-05-01 16:47       ` Matt Roper
2015-04-07 22:28 ` [PATCH 14/14] drm/i915: skylake sprite " Chandra Konduru
2015-04-09 23:43   ` Chandra Konduru
2015-04-10  0:01     ` Matt Roper
2015-04-15 22:15   ` Chandra Konduru
2015-04-16  7:42     ` Daniel Vetter
2015-04-16  8:18     ` Jindal, Sonika
2015-04-09 21:53 ` [PATCH 00/14] skylake display scalers Matt Roper
2015-04-09 22:12   ` Matt Roper
2015-04-09 22:22     ` Konduru, Chandra
2015-04-10  9:34 ` Daniel Vetter
2015-04-10 16:29   ` Konduru, Chandra

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.