* [v2 00/11] Support for 180 degree HW rotation
@ 2014-07-04 9:43 sonika.jindal
2014-07-04 9:43 ` [v2 01/11] drm: Move DRM_ROTATE bits out of omapdrm into drm_crtc.h sonika.jindal
` (11 more replies)
0 siblings, 12 replies; 19+ messages in thread
From: sonika.jindal @ 2014-07-04 9:43 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel
From: Sonika Jindal <sonika.jindal@intel.com>
Enables 180 degree rotation for sprite and primary planes.
Updated the primary plane rotation support as per the new universal plane
design.
Most of these patches were already reviewed in intel-gfx in February 2014 thats
why there is version history in few of them.
v2: Moved rotation_property to drm_plane. Added updation of FBC when rotation is
again set to 0.
Testcase: kms_rotation_crc
This igt can be extended for clipped rotation cases. Right it only tests 180
degree rotation for sprite and primary plane with crc check.
Sonika Jindal (2):
drm/i915: Add 180 degree primary plane rotation support
drm: Resetting rotation property
Ville Syrjälä (9):
drm: Move DRM_ROTATE bits out of omapdrm into drm_crtc.h
drm: Add support_bits parameter to drm_property_create_bitmask()
drm: Add drm_mode_create_rotation_property()
drm/omap: Switch omapdrm over to drm_mode_create_rotation_property()
drm: Add drm_rect rotation functions
drm: Add drm_rotation_simplify()
drm/i915: Add 180 degree sprite rotation support
drm/i915: Make intel_plane_restore() return an error
drm/i915: Add rotation property for sprites
drivers/gpu/drm/drm_crtc.c | 65 +++++++++++++++-
drivers/gpu/drm/drm_fb_helper.c | 16 +++-
drivers/gpu/drm/drm_rect.c | 140 ++++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/i915_reg.h | 4 +
drivers/gpu/drm/i915/intel_display.c | 102 +++++++++++++++++++++++--
drivers/gpu/drm/i915/intel_drv.h | 3 +-
drivers/gpu/drm/i915/intel_pm.c | 7 ++
drivers/gpu/drm/i915/intel_sprite.c | 91 ++++++++++++++++++++--
drivers/gpu/drm/omapdrm/omap_drv.h | 7 --
drivers/gpu/drm/omapdrm/omap_plane.c | 17 ++---
include/drm/drm_crtc.h | 16 +++-
include/drm/drm_rect.h | 6 ++
12 files changed, 437 insertions(+), 37 deletions(-)
--
1.7.10.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 19+ messages in thread
* [v2 01/11] drm: Move DRM_ROTATE bits out of omapdrm into drm_crtc.h
2014-07-04 9:43 [v2 00/11] Support for 180 degree HW rotation sonika.jindal
@ 2014-07-04 9:43 ` sonika.jindal
2014-07-04 9:43 ` [v2 02/11] drm: Add support_bits parameter to drm_property_create_bitmask() sonika.jindal
` (10 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: sonika.jindal @ 2014-07-04 9:43 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel
From: Ville Syrjälä <ville.syrjala at linux.intel.com>
The rotation property stuff should be standardized among all drivers.
Move the bits to drm_crtc.h from omap_drv.h.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/omapdrm/omap_drv.h | 7 -------
include/drm/drm_crtc.h | 8 ++++++++
2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index 284b80f..b08a450 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -119,13 +119,6 @@ struct omap_drm_private {
struct omap_drm_irq error_handler;
};
-/* this should probably be in drm-core to standardize amongst drivers */
-#define DRM_ROTATE_0 0
-#define DRM_ROTATE_90 1
-#define DRM_ROTATE_180 2
-#define DRM_ROTATE_270 3
-#define DRM_REFLECT_X 4
-#define DRM_REFLECT_Y 5
#ifdef CONFIG_DEBUG_FS
int omap_debugfs_init(struct drm_minor *minor);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 4ee7e26..bfc7235 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -75,6 +75,14 @@ static inline uint64_t I642U64(int64_t val)
return (uint64_t)*((uint64_t *)&val);
}
+/* rotation property bits */
+#define DRM_ROTATE_0 0
+#define DRM_ROTATE_90 1
+#define DRM_ROTATE_180 2
+#define DRM_ROTATE_270 3
+#define DRM_REFLECT_X 4
+#define DRM_REFLECT_Y 5
+
enum drm_connector_force {
DRM_FORCE_UNSPECIFIED,
DRM_FORCE_OFF,
--
1.7.10.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [v2 02/11] drm: Add support_bits parameter to drm_property_create_bitmask()
2014-07-04 9:43 [v2 00/11] Support for 180 degree HW rotation sonika.jindal
2014-07-04 9:43 ` [v2 01/11] drm: Move DRM_ROTATE bits out of omapdrm into drm_crtc.h sonika.jindal
@ 2014-07-04 9:43 ` sonika.jindal
2014-07-04 9:43 ` [v2 03/11] drm: Add drm_mode_create_rotation_property() sonika.jindal
` (9 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: sonika.jindal @ 2014-07-04 9:43 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel
From: Ville Syrjälä <ville.syrjala at linux.intel.com>
Make drm_property_create_bitmask() a bit more generic by allowing the
caller to specify which bits are in fact supported. This allows multiple
callers to use the same enum list, but still create different versions
of the same property with different list of supported bits.
v2: Populate values[] array as non-sparse
Make supported_bits 64bit
Fix up omapdrm call site (Rob)
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Sagar Kamble <sagar.a.kamble@intel.com>
---
drivers/gpu/drm/drm_crtc.c | 17 +++++++++++++----
drivers/gpu/drm/omapdrm/omap_plane.c | 5 ++++-
include/drm/drm_crtc.h | 3 ++-
3 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 41c7212..2fbee61 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -3395,19 +3395,28 @@ EXPORT_SYMBOL(drm_property_create_enum);
struct drm_property *drm_property_create_bitmask(struct drm_device *dev,
int flags, const char *name,
const struct drm_prop_enum_list *props,
- int num_values)
+ int num_props,
+ uint64_t supported_bits)
{
struct drm_property *property;
- int i, ret;
+ int i, ret, index = 0;
+ int num_values = hweight64(supported_bits);
flags |= DRM_MODE_PROP_BITMASK;
property = drm_property_create(dev, flags, name, num_values);
if (!property)
return NULL;
+ for (i = 0; i < num_props; i++) {
+ if (!(supported_bits & (1ULL << props[i].type)))
+ continue;
- for (i = 0; i < num_values; i++) {
- ret = drm_property_add_enum(property, i,
+ if (WARN_ON(index >= num_values)) {
+ drm_property_destroy(dev, property);
+ return NULL;
+ }
+
+ ret = drm_property_add_enum(property, index++,
props[i].type,
props[i].name);
if (ret) {
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index 3cf31ee..aff06e7 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -317,7 +317,10 @@ void omap_plane_install_properties(struct drm_plane *plane,
{ DRM_REFLECT_Y, "reflect-y" },
};
prop = drm_property_create_bitmask(dev, 0, "rotation",
- props, ARRAY_SIZE(props));
+ props, ARRAY_SIZE(props),
+ BIT(DRM_ROTATE_0) | BIT(DRM_ROTATE_90) |
+ BIT(DRM_ROTATE_180) | BIT(DRM_ROTATE_270) |
+ BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y));
if (prop == NULL)
return;
priv->rotation_prop = prop;
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index bfc7235..cb4850a 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1006,7 +1006,8 @@ extern struct drm_property *drm_property_create_enum(struct drm_device *dev, int
struct drm_property *drm_property_create_bitmask(struct drm_device *dev,
int flags, const char *name,
const struct drm_prop_enum_list *props,
- int num_values);
+ int num_props,
+ uint64_t supported_bits);
struct drm_property *drm_property_create_range(struct drm_device *dev, int flags,
const char *name,
uint64_t min, uint64_t max);
--
1.7.10.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [v2 03/11] drm: Add drm_mode_create_rotation_property()
2014-07-04 9:43 [v2 00/11] Support for 180 degree HW rotation sonika.jindal
2014-07-04 9:43 ` [v2 01/11] drm: Move DRM_ROTATE bits out of omapdrm into drm_crtc.h sonika.jindal
2014-07-04 9:43 ` [v2 02/11] drm: Add support_bits parameter to drm_property_create_bitmask() sonika.jindal
@ 2014-07-04 9:43 ` sonika.jindal
2014-07-04 9:43 ` [v2 04/11] drm/omap: Switch omapdrm over to drm_mode_create_rotation_property() sonika.jindal
` (8 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: sonika.jindal @ 2014-07-04 9:43 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel
From: Ville Syrjälä <ville.syrjala at linux.intel.com>
Add a function to create a standards compliant rotation property.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/drm_crtc.c | 18 ++++++++++++++++++
include/drm/drm_crtc.h | 2 ++
2 files changed, 20 insertions(+)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 2fbee61..f224d4d 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -4959,3 +4959,21 @@ void drm_mode_config_cleanup(struct drm_device *dev)
drm_modeset_lock_fini(&dev->mode_config.connection_mutex);
}
EXPORT_SYMBOL(drm_mode_config_cleanup);
+
+struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
+ unsigned int supported_rotations)
+{
+ static const struct drm_prop_enum_list props[] = {
+ { DRM_ROTATE_0, "rotate-0" },
+ { DRM_ROTATE_90, "rotate-90" },
+ { DRM_ROTATE_180, "rotate-180" },
+ { DRM_ROTATE_270, "rotate-270" },
+ { DRM_REFLECT_X, "reflect-x" },
+ { DRM_REFLECT_Y, "reflect-y" },
+ };
+
+ return drm_property_create_bitmask(dev, 0, "rotation",
+ props, ARRAY_SIZE(props),
+ supported_rotations);
+}
+EXPORT_SYMBOL(drm_mode_create_rotation_property);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index cb4850a..f7b383b 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1113,6 +1113,8 @@ extern int drm_format_plane_cpp(uint32_t format, int plane);
extern int drm_format_horz_chroma_subsampling(uint32_t format);
extern int drm_format_vert_chroma_subsampling(uint32_t format);
extern const char *drm_get_format_name(uint32_t format);
+extern struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
+ unsigned int supported_rotations);
/* Helpers */
--
1.7.10.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [v2 04/11] drm/omap: Switch omapdrm over to drm_mode_create_rotation_property()
2014-07-04 9:43 [v2 00/11] Support for 180 degree HW rotation sonika.jindal
` (2 preceding siblings ...)
2014-07-04 9:43 ` [v2 03/11] drm: Add drm_mode_create_rotation_property() sonika.jindal
@ 2014-07-04 9:43 ` sonika.jindal
2014-07-04 9:43 ` [v2 05/11] drm: Add drm_rect rotation functions sonika.jindal
` (7 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: sonika.jindal @ 2014-07-04 9:43 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel
From: Ville Syrjälä <ville.syrjala at linux.intel.com>
Use the new drm_mode_create_rotation_property() in omapdrm.
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Rob Clark <robdclark@gmail.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Sagar Kamble <sagar.a.kamble@intel.com>
---
drivers/gpu/drm/omapdrm/omap_plane.c | 20 +++++++-------------
1 file changed, 7 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index aff06e7..da9d15d 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -308,19 +308,13 @@ void omap_plane_install_properties(struct drm_plane *plane,
if (priv->has_dmm) {
prop = priv->rotation_prop;
if (!prop) {
- const struct drm_prop_enum_list props[] = {
- { DRM_ROTATE_0, "rotate-0" },
- { DRM_ROTATE_90, "rotate-90" },
- { DRM_ROTATE_180, "rotate-180" },
- { DRM_ROTATE_270, "rotate-270" },
- { DRM_REFLECT_X, "reflect-x" },
- { DRM_REFLECT_Y, "reflect-y" },
- };
- prop = drm_property_create_bitmask(dev, 0, "rotation",
- props, ARRAY_SIZE(props),
- BIT(DRM_ROTATE_0) | BIT(DRM_ROTATE_90) |
- BIT(DRM_ROTATE_180) | BIT(DRM_ROTATE_270) |
- BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y));
+ prop = drm_mode_create_rotation_property(dev,
+ BIT(DRM_ROTATE_0) |
+ BIT(DRM_ROTATE_90) |
+ BIT(DRM_ROTATE_180) |
+ BIT(DRM_ROTATE_270) |
+ BIT(DRM_REFLECT_X) |
+ BIT(DRM_REFLECT_Y));
if (prop == NULL)
return;
priv->rotation_prop = prop;
--
1.7.10.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [v2 05/11] drm: Add drm_rect rotation functions
2014-07-04 9:43 [v2 00/11] Support for 180 degree HW rotation sonika.jindal
` (3 preceding siblings ...)
2014-07-04 9:43 ` [v2 04/11] drm/omap: Switch omapdrm over to drm_mode_create_rotation_property() sonika.jindal
@ 2014-07-04 9:43 ` sonika.jindal
2014-07-04 9:43 ` [v2 06/11] drm: Add drm_rotation_simplify() sonika.jindal
` (6 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: sonika.jindal @ 2014-07-04 9:43 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel
From: Ville Syrjälä <ville.syrjala at linux.intel.com>
Add some helper functions to move drm_rects between different rotated
coordinate spaces. One function does the forward transform and
another does the inverse.
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/drm_rect.c | 140 ++++++++++++++++++++++++++++++++++++++++++++
include/drm/drm_rect.h | 6 ++
2 files changed, 146 insertions(+)
diff --git a/drivers/gpu/drm/drm_rect.c b/drivers/gpu/drm/drm_rect.c
index 7047ca0..631f5af 100644
--- a/drivers/gpu/drm/drm_rect.c
+++ b/drivers/gpu/drm/drm_rect.c
@@ -293,3 +293,143 @@ void drm_rect_debug_print(const struct drm_rect *r, bool fixed_point)
DRM_DEBUG_KMS("%dx%d%+d%+d\n", w, h, r->x1, r->y1);
}
EXPORT_SYMBOL(drm_rect_debug_print);
+
+/**
+ * drm_rect_rotate - Rotate the rectangle
+ * @r: rectangle to be rotated
+ * @width: Width of the coordinate space
+ * @height: Height of the coordinate space
+ * @rotation: Transformation to be applied
+ *
+ * Apply @rotation to the coordinates of rectangle @r.
+ *
+ * @width and @height combined with @rotation define
+ * the location of the new origin.
+ *
+ * @width correcsponds to the horizontal and @height
+ * to the vertical axis of the untransformed coordinate
+ * space.
+ */
+void drm_rect_rotate(struct drm_rect *r,
+ int width, int height,
+ unsigned int rotation)
+{
+ struct drm_rect tmp;
+
+ if (rotation & (BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y))) {
+ tmp = *r;
+
+ if (rotation & BIT(DRM_REFLECT_X)) {
+ r->x1 = width - tmp.x2;
+ r->x2 = width - tmp.x1;
+ }
+
+ if (rotation & BIT(DRM_REFLECT_Y)) {
+ r->y1 = height - tmp.y2;
+ r->y2 = height - tmp.y1;
+ }
+ }
+
+ switch (rotation & 0xf) {
+ case BIT(DRM_ROTATE_0):
+ break;
+ case BIT(DRM_ROTATE_90):
+ tmp = *r;
+ r->x1 = tmp.y1;
+ r->x2 = tmp.y2;
+ r->y1 = width - tmp.x2;
+ r->y2 = width - tmp.x1;
+ break;
+ case BIT(DRM_ROTATE_180):
+ tmp = *r;
+ r->x1 = width - tmp.x2;
+ r->x2 = width - tmp.x1;
+ r->y1 = height - tmp.y2;
+ r->y2 = height - tmp.y1;
+ break;
+ case BIT(DRM_ROTATE_270):
+ tmp = *r;
+ r->x1 = height - tmp.y2;
+ r->x2 = height - tmp.y1;
+ r->y1 = tmp.x1;
+ r->y2 = tmp.x2;
+ break;
+ default:
+ break;
+ }
+}
+EXPORT_SYMBOL(drm_rect_rotate);
+
+/**
+ * drm_rect_rotate_inv - Inverse rotate the rectangle
+ * @r: rectangle to be rotated
+ * @width: Width of the coordinate space
+ * @height: Height of the coordinate space
+ * @rotation: Transformation whose inverse is to be applied
+ *
+ * Apply the inverse of @rotation to the coordinates
+ * of rectangle @r.
+ *
+ * @width and @height combined with @rotation define
+ * the location of the new origin.
+ *
+ * @width correcsponds to the horizontal and @height
+ * to the vertical axis of the original untransformed
+ * coordinate space, so that you never have to flip
+ * them when doing a rotatation and its inverse.
+ * That is, if you do:
+ *
+ * drm_rotate(&r, width, height, rotation);
+ * drm_rotate_inv(&r, width, height, rotation);
+ *
+ * you will always get back the original rectangle.
+ */
+void drm_rect_rotate_inv(struct drm_rect *r,
+ int width, int height,
+ unsigned int rotation)
+{
+ struct drm_rect tmp;
+
+ switch (rotation & 0xf) {
+ case BIT(DRM_ROTATE_0):
+ break;
+ case BIT(DRM_ROTATE_90):
+ tmp = *r;
+ r->x1 = width - tmp.y2;
+ r->x2 = width - tmp.y1;
+ r->y1 = tmp.x1;
+ r->y2 = tmp.x2;
+ break;
+ case BIT(DRM_ROTATE_180):
+ tmp = *r;
+ r->x1 = width - tmp.x2;
+ r->x2 = width - tmp.x1;
+ r->y1 = height - tmp.y2;
+ r->y2 = height - tmp.y1;
+ break;
+ case BIT(DRM_ROTATE_270):
+ tmp = *r;
+ r->x1 = tmp.y1;
+ r->x2 = tmp.y2;
+ r->y1 = height - tmp.x2;
+ r->y2 = height - tmp.x1;
+ break;
+ default:
+ break;
+ }
+
+ if (rotation & (BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y))) {
+ tmp = *r;
+
+ if (rotation & BIT(DRM_REFLECT_X)) {
+ r->x1 = width - tmp.x2;
+ r->x2 = width - tmp.x1;
+ }
+
+ if (rotation & BIT(DRM_REFLECT_Y)) {
+ r->y1 = height - tmp.y2;
+ r->y2 = height - tmp.y1;
+ }
+ }
+}
+EXPORT_SYMBOL(drm_rect_rotate_inv);
diff --git a/include/drm/drm_rect.h b/include/drm/drm_rect.h
index d128629..26bb55e 100644
--- a/include/drm/drm_rect.h
+++ b/include/drm/drm_rect.h
@@ -163,5 +163,11 @@ int drm_rect_calc_vscale_relaxed(struct drm_rect *src,
struct drm_rect *dst,
int min_vscale, int max_vscale);
void drm_rect_debug_print(const struct drm_rect *r, bool fixed_point);
+void drm_rect_rotate(struct drm_rect *r,
+ int width, int height,
+ unsigned int rotation);
+void drm_rect_rotate_inv(struct drm_rect *r,
+ int width, int height,
+ unsigned int rotation);
#endif
--
1.7.10.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [v2 06/11] drm: Add drm_rotation_simplify()
2014-07-04 9:43 [v2 00/11] Support for 180 degree HW rotation sonika.jindal
` (4 preceding siblings ...)
2014-07-04 9:43 ` [v2 05/11] drm: Add drm_rect rotation functions sonika.jindal
@ 2014-07-04 9:43 ` sonika.jindal
2014-07-04 9:43 ` [v2 07/11] drm/i915: Add 180 degree sprite rotation support sonika.jindal
` (5 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: sonika.jindal @ 2014-07-04 9:43 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel
From: Ville Syrjälä <ville.syrjala at linux.intel.com>
drm_rotation_simplify() can be used to eliminate unsupported rotation
flags. It will check if any unsupported flags are present, and if so
it will modify the rotation to an alternate form by adding 180 degrees
to rotation angle, and flipping the reflect x and y bits. The hope is
that this identity transform will eliminate the unsupported flags.
Of course that might not result in any more supported rotation, so
the caller is still responsible for checking the result afterwards.
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/drm_crtc.c | 30 ++++++++++++++++++++++++++++++
include/drm/drm_crtc.h | 2 ++
2 files changed, 32 insertions(+)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index f224d4d..89bab66 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -4842,6 +4842,36 @@ int drm_format_vert_chroma_subsampling(uint32_t format)
EXPORT_SYMBOL(drm_format_vert_chroma_subsampling);
/**
+ * drm_rotation_simplify() - Try to simplify the rotation
+ * @rotation: Rotation to be simplified
+ * @supported_rotations: Supported rotations
+ *
+ * Attempt to simplify the rotation to a form that is supported.
+ * Eg. if the hardware supports everything except DRM_REFLECT_X
+ * one could call this function like this:
+ *
+ * drm_rotation_simplify(rotation, BIT(DRM_ROTATE_0) |
+ * BIT(DRM_ROTATE_90) | BIT(DRM_ROTATE_180) |
+ * BIT(DRM_ROTATE_270) | BIT(DRM_REFLECT_Y));
+ *
+ * to eliminate the DRM_ROTATE_X flag. Depending on what kind of
+ * transforms the hardware supports, this function may not
+ * be able to produce a supported transform, so the caller should
+ * check the result afterwards.
+ */
+unsigned int drm_rotation_simplify(unsigned int rotation,
+ unsigned int supported_rotations)
+{
+ if (rotation & ~supported_rotations) {
+ rotation ^= BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y);
+ rotation = (rotation & ~0xf) | BIT((ffs(rotation & 0xf) + 1) % 4);
+ }
+
+ return rotation;
+}
+EXPORT_SYMBOL(drm_rotation_simplify);
+
+/**
* drm_mode_config_init - initialize DRM mode_configuration structure
* @dev: DRM device
*
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index f7b383b..08ed55e 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1115,6 +1115,8 @@ extern int drm_format_vert_chroma_subsampling(uint32_t format);
extern const char *drm_get_format_name(uint32_t format);
extern struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
unsigned int supported_rotations);
+extern unsigned int drm_rotation_simplify(unsigned int rotation,
+ unsigned int supported_rotations);
/* Helpers */
--
1.7.10.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [v2 07/11] drm/i915: Add 180 degree sprite rotation support
2014-07-04 9:43 [v2 00/11] Support for 180 degree HW rotation sonika.jindal
` (5 preceding siblings ...)
2014-07-04 9:43 ` [v2 06/11] drm: Add drm_rotation_simplify() sonika.jindal
@ 2014-07-04 9:43 ` sonika.jindal
2014-07-04 9:44 ` [v2 08/11] drm/i915: Make intel_plane_restore() return an error sonika.jindal
` (4 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: sonika.jindal @ 2014-07-04 9:43 UTC (permalink / raw)
To: intel-gfx; +Cc: Sagar Kamble, dri-devel
From: Ville Syrjälä <ville.syrjala at linux.intel.com>
The sprite planes (in fact all display planes starting from gen4)
support 180 degree rotation. Add the relevant low level bits to the
sprite code to make use of that feature.
The upper layers are not yet plugged in.
v2: HSW handles the rotated buffer offset automagically
v3: BDW also handles the rotated buffer offset automagically
Testcase: igt/kms_rotation_crc
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Sagar Kamble <sagar.a.kamble@intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/i915_reg.h | 3 +++
drivers/gpu/drm/i915/intel_drv.h | 1 +
drivers/gpu/drm/i915/intel_sprite.c | 37 +++++++++++++++++++++++++++++++++++
3 files changed, 41 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 3488567..c70c804 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4171,6 +4171,7 @@ enum punit_power_well {
#define DVS_YUV_ORDER_UYVY (1<<16)
#define DVS_YUV_ORDER_YVYU (2<<16)
#define DVS_YUV_ORDER_VYUY (3<<16)
+#define DVS_ROTATE_180 (1<<15)
#define DVS_DEST_KEY (1<<2)
#define DVS_TRICKLE_FEED_DISABLE (1<<14)
#define DVS_TILED (1<<10)
@@ -4241,6 +4242,7 @@ enum punit_power_well {
#define SPRITE_YUV_ORDER_UYVY (1<<16)
#define SPRITE_YUV_ORDER_YVYU (2<<16)
#define SPRITE_YUV_ORDER_VYUY (3<<16)
+#define SPRITE_ROTATE_180 (1<<15)
#define SPRITE_TRICKLE_FEED_DISABLE (1<<14)
#define SPRITE_INT_GAMMA_ENABLE (1<<13)
#define SPRITE_TILED (1<<10)
@@ -4314,6 +4316,7 @@ enum punit_power_well {
#define SP_YUV_ORDER_UYVY (1<<16)
#define SP_YUV_ORDER_YVYU (2<<16)
#define SP_YUV_ORDER_VYUY (3<<16)
+#define SP_ROTATE_180 (1<<15)
#define SP_TILED (1<<10)
#define _SPALINOFF (VLV_DISPLAY_BASE + 0x72184)
#define _SPASTRIDE (VLV_DISPLAY_BASE + 0x72188)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index ab5962b..67b1c59 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -437,6 +437,7 @@ struct intel_plane {
unsigned int crtc_w, crtc_h;
uint32_t src_x, src_y;
uint32_t src_w, src_h;
+ unsigned int rotation;
/* Since we need to change the watermarks before/after
* enabling/disabling the planes, we need to store the parameters here
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 404335d..54d4224 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -163,6 +163,7 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
sprctl &= ~SP_PIXFORMAT_MASK;
sprctl &= ~SP_YUV_BYTE_ORDER_MASK;
sprctl &= ~SP_TILED;
+ sprctl &= ~SP_ROTATE_180;
switch (fb->pixel_format) {
case DRM_FORMAT_YUYV:
@@ -234,6 +235,14 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
fb->pitches[0]);
linear_offset -= sprsurf_offset;
+ if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
+ sprctl |= SP_ROTATE_180;
+
+ x += src_w;
+ y += src_h;
+ linear_offset += src_h * fb->pitches[0] + src_w * pixel_size;
+ }
+
atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
intel_update_primary_plane(intel_crtc);
@@ -363,6 +372,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
sprctl &= ~SPRITE_RGB_ORDER_RGBX;
sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK;
sprctl &= ~SPRITE_TILED;
+ sprctl &= ~SPRITE_ROTATE_180;
switch (fb->pixel_format) {
case DRM_FORMAT_XBGR8888:
@@ -424,6 +434,17 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
pixel_size, fb->pitches[0]);
linear_offset -= sprsurf_offset;
+ if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
+ sprctl |= SPRITE_ROTATE_180;
+
+ /* HSW and BDW does this automagically in hardware */
+ if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) {
+ x += src_w;
+ y += src_h;
+ linear_offset += src_h * fb->pitches[0] + src_w * pixel_size;
+ }
+ }
+
atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
intel_update_primary_plane(intel_crtc);
@@ -569,6 +590,7 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
dvscntr &= ~DVS_RGB_ORDER_XBGR;
dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK;
dvscntr &= ~DVS_TILED;
+ dvscntr &= ~DVS_ROTATE_180;
switch (fb->pixel_format) {
case DRM_FORMAT_XBGR8888:
@@ -625,6 +647,14 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
pixel_size, fb->pitches[0]);
linear_offset -= dvssurf_offset;
+ if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
+ dvscntr |= DVS_ROTATE_180;
+
+ x += src_w;
+ y += src_h;
+ linear_offset += src_h * fb->pitches[0] + src_w * pixel_size;
+ }
+
atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
intel_update_primary_plane(intel_crtc);
@@ -883,6 +913,9 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
max_scale = intel_plane->max_downscale << 16;
min_scale = intel_plane->can_scale ? 1 : (1 << 16);
+ drm_rect_rotate(&src, fb->width << 16, fb->height << 16,
+ intel_plane->rotation);
+
hscale = drm_rect_calc_hscale_relaxed(&src, &dst, min_scale, max_scale);
BUG_ON(hscale < 0);
@@ -921,6 +954,9 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
drm_rect_width(&dst) * hscale - drm_rect_width(&src),
drm_rect_height(&dst) * vscale - drm_rect_height(&src));
+ drm_rect_rotate_inv(&src, fb->width << 16, fb->height << 16,
+ intel_plane->rotation);
+
/* sanity check to make sure the src viewport wasn't enlarged */
WARN_ON(src.x1 < (int) src_x ||
src.y1 < (int) src_y ||
@@ -1296,6 +1332,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
intel_plane->pipe = pipe;
intel_plane->plane = plane;
+ intel_plane->rotation = BIT(DRM_ROTATE_0);
possible_crtcs = (1 << pipe);
ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs,
&intel_plane_funcs,
--
1.7.10.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [v2 08/11] drm/i915: Make intel_plane_restore() return an error
2014-07-04 9:43 [v2 00/11] Support for 180 degree HW rotation sonika.jindal
` (6 preceding siblings ...)
2014-07-04 9:43 ` [v2 07/11] drm/i915: Add 180 degree sprite rotation support sonika.jindal
@ 2014-07-04 9:44 ` sonika.jindal
2014-07-04 9:44 ` [v2 09/11] drm/i915: Add rotation property for sprites sonika.jindal
` (3 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: sonika.jindal @ 2014-07-04 9:44 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel
From: Ville Syrjälä <ville.syrjala at linux.intel.com>
Propagate the error from intel_update_plane() up through
intel_plane_restore() to the caller. This will be used for
rollback purposes when setting properties fails.
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/intel_drv.h | 2 +-
drivers/gpu/drm/i915/intel_sprite.c | 14 +++++++-------
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 67b1c59..da5a3ca 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -993,7 +993,7 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
enum plane plane);
-void intel_plane_restore(struct drm_plane *plane);
+int intel_plane_restore(struct drm_plane *plane);
void intel_plane_disable(struct drm_plane *plane);
int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
struct drm_file *file_priv);
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 54d4224..cbad738 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -1202,18 +1202,18 @@ out_unlock:
return ret;
}
-void intel_plane_restore(struct drm_plane *plane)
+int intel_plane_restore(struct drm_plane *plane)
{
struct intel_plane *intel_plane = to_intel_plane(plane);
if (!plane->crtc || !plane->fb)
- return;
+ return 0;
- intel_update_plane(plane, plane->crtc, plane->fb,
- intel_plane->crtc_x, intel_plane->crtc_y,
- intel_plane->crtc_w, intel_plane->crtc_h,
- intel_plane->src_x, intel_plane->src_y,
- intel_plane->src_w, intel_plane->src_h);
+ return intel_update_plane(plane, plane->crtc, plane->fb,
+ intel_plane->crtc_x, intel_plane->crtc_y,
+ intel_plane->crtc_w, intel_plane->crtc_h,
+ intel_plane->src_x, intel_plane->src_y,
+ intel_plane->src_w, intel_plane->src_h);
}
void intel_plane_disable(struct drm_plane *plane)
--
1.7.10.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [v2 09/11] drm/i915: Add rotation property for sprites
2014-07-04 9:43 [v2 00/11] Support for 180 degree HW rotation sonika.jindal
` (7 preceding siblings ...)
2014-07-04 9:44 ` [v2 08/11] drm/i915: Make intel_plane_restore() return an error sonika.jindal
@ 2014-07-04 9:44 ` sonika.jindal
2014-07-04 9:44 ` [v2 10/11] drm/i915: Add 180 degree primary plane rotation support sonika.jindal
` (2 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: sonika.jindal @ 2014-07-04 9:44 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel
From: Ville Syrjälä <ville.syrjala at linux.intel.com>
Sprite planes support 180 degree rotation. The lower layers are now in
place, so hook in the standard rotation property to expose the feature
to the users.
v2: Moving rotation_property to drm_plane
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/intel_sprite.c | 40 ++++++++++++++++++++++++++++++++++-
include/drm/drm_crtc.h | 1 +
2 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index cbad738..aa63027 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -1202,6 +1202,29 @@ out_unlock:
return ret;
}
+static int intel_plane_set_property(struct drm_plane *plane,
+ struct drm_property *prop,
+ uint64_t val)
+{
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+ uint64_t old_val;
+ int ret = -ENOENT;
+
+ if (prop == plane->rotation_property) {
+ /* exactly one rotation angle please */
+ if (hweight32(val & 0xf) != 1)
+ return -EINVAL;
+
+ old_val = intel_plane->rotation;
+ intel_plane->rotation = val;
+ ret = intel_plane_restore(plane);
+ if (ret)
+ intel_plane->rotation = old_val;
+ }
+
+ return ret;
+}
+
int intel_plane_restore(struct drm_plane *plane)
{
struct intel_plane *intel_plane = to_intel_plane(plane);
@@ -1228,6 +1251,7 @@ static const struct drm_plane_funcs intel_plane_funcs = {
.update_plane = intel_update_plane,
.disable_plane = intel_disable_plane,
.destroy = intel_destroy_plane,
+ .set_property = intel_plane_set_property,
};
static uint32_t ilk_plane_formats[] = {
@@ -1338,8 +1362,22 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
&intel_plane_funcs,
plane_formats, num_plane_formats,
false);
- if (ret)
+ if (ret) {
kfree(intel_plane);
+ goto out;
+ }
+
+ if (!intel_plane->base.rotation_property)
+ intel_plane->base.rotation_property =
+ drm_mode_create_rotation_property(dev,
+ BIT(DRM_ROTATE_0) |
+ BIT(DRM_ROTATE_180));
+
+ if (intel_plane->base.rotation_property)
+ drm_object_attach_property(&intel_plane->base.base,
+ intel_plane->base.rotation_property,
+ intel_plane->rotation);
+ out:
return ret;
}
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 08ed55e..6006c70 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -615,6 +615,7 @@ struct drm_plane {
const struct drm_plane_funcs *funcs;
+ struct drm_property *rotation_property;
struct drm_object_properties properties;
enum drm_plane_type type;
--
1.7.10.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [v2 10/11] drm/i915: Add 180 degree primary plane rotation support
2014-07-04 9:43 [v2 00/11] Support for 180 degree HW rotation sonika.jindal
` (8 preceding siblings ...)
2014-07-04 9:44 ` [v2 09/11] drm/i915: Add rotation property for sprites sonika.jindal
@ 2014-07-04 9:44 ` sonika.jindal
2014-07-04 14:58 ` Damien Lespiau
2014-07-04 9:44 ` [v2 11/11] drm: Resetting rotation property sonika.jindal
2014-07-04 15:06 ` [v2 00/11] Support for 180 degree HW rotation Damien Lespiau
11 siblings, 1 reply; 19+ messages in thread
From: sonika.jindal @ 2014-07-04 9:44 UTC (permalink / raw)
To: intel-gfx; +Cc: Sagar Kamble, dri-devel
From: Sonika Jindal <sonika.jindal@intel.com>
Primary planes support 180 degree rotation. Expose the feature
through rotation drm property.
v2: Calculating linear/tiled offsets based on pipe source width and
height. Added 180 degree rotation support in ironlake_update_plane.
v3: Checking if CRTC is active before issueing update_plane. Added
wait for vblank to make sure we dont overtake page flips. Disabling
FBC since it does not work with rotated planes.
v4: Updated rotation checks for pending flips, fbc disable. Creating
rotation property only for Gen4 onwards. Property resetting as part
of lastclose.
v5: Resetting property in i915_driver_lastclose properly for planes
and crtcs. Fixed linear offset calculation that was off by 1 w.r.t
width in i9xx_update_plane and ironlake_update_plane. Removed tab
based indentation and unnecessary braces in intel_crtc_set_property
and intel_update_fbc. FBC and flip related checks should be done only
for valid crtcs.
v6: Minor nits in FBC disable checks for comments in intel_crtc_set_property
and positioning the disable code in intel_update_fbc.
v7: In case rotation property on inactive crtc is updated, we return
successfully printing debug log as crtc is inactive and only property change
is preserved.
v8: update_plane is changed to update_primary_plane, crtc->fb is changed to
crtc->primary->fb and return value of update_primary_plane is ignored.
v9: added rotation property to primary plane instead of crtc. Removing reset
of rotation property from lastclose. rotation_property is moved to drm_plane,so
drm layer will take care of resetting.
v10: adding updation of fbc when rotation is set to 0.
Testcase: igt/kms_rotation_crc
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Sagar Kamble <sagar.a.kamble@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
drivers/gpu/drm/i915/i915_reg.h | 1 +
drivers/gpu/drm/i915/intel_display.c | 102 ++++++++++++++++++++++++++++++++--
drivers/gpu/drm/i915/intel_pm.c | 7 +++
3 files changed, 105 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index c70c804..c600d3b 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4087,6 +4087,7 @@ enum punit_power_well {
#define DISPPLANE_NO_LINE_DOUBLE 0
#define DISPPLANE_STEREO_POLARITY_FIRST 0
#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
+#define DISPPLANE_ROTATE_180 (1<<15)
#define DISPPLANE_TRICKLE_FEED_DISABLE (1<<14) /* Ironlake */
#define DISPPLANE_TILED (1<<10)
#define _DSPAADDR 0x70184
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 5e8e711..7f16d6f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2414,7 +2414,9 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
unsigned long linear_offset;
u32 dspcntr;
u32 reg;
+ int pixel_size;
+ pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
intel_fb = to_intel_framebuffer(fb);
obj = intel_fb->obj;
@@ -2422,6 +2424,8 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
dspcntr = I915_READ(reg);
/* Mask out pixel format bits in case we change it */
dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
+ dspcntr &= ~DISPPLANE_ROTATE_180;
+
switch (fb->pixel_format) {
case DRM_FORMAT_C8:
dspcntr |= DISPPLANE_8BPP;
@@ -2463,8 +2467,6 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
if (IS_G4X(dev))
dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
- I915_WRITE(reg, dspcntr);
-
linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
if (INTEL_INFO(dev)->gen >= 4) {
@@ -2477,6 +2479,18 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
intel_crtc->dspaddr_offset = linear_offset;
}
+ if (to_intel_plane(crtc->primary)->rotation == BIT(DRM_ROTATE_180)) {
+ dspcntr |= DISPPLANE_ROTATE_180;
+
+ x += (intel_crtc->config.pipe_src_w - 1);
+ y += (intel_crtc->config.pipe_src_h - 1);
+ linear_offset += (intel_crtc->config.pipe_src_h - 1) *
+ fb->pitches[0] +
+ (intel_crtc->config.pipe_src_w - 1) * pixel_size;
+ }
+
+ I915_WRITE(reg, dspcntr);
+
DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n",
i915_gem_obj_ggtt_offset(obj), linear_offset, x, y,
fb->pitches[0]);
@@ -2487,7 +2501,8 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
I915_WRITE(DSPTILEOFF(plane), (y << 16) | x);
I915_WRITE(DSPLINOFF(plane), linear_offset);
} else
- I915_WRITE(DSPADDR(plane), i915_gem_obj_ggtt_offset(obj) + linear_offset);
+ I915_WRITE(DSPADDR(plane), i915_gem_obj_ggtt_offset(obj) +
+ linear_offset);
POSTING_READ(reg);
}
@@ -2504,7 +2519,9 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
unsigned long linear_offset;
u32 dspcntr;
u32 reg;
+ int pixel_size;
+ pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
intel_fb = to_intel_framebuffer(fb);
obj = intel_fb->obj;
@@ -2512,6 +2529,8 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
dspcntr = I915_READ(reg);
/* Mask out pixel format bits in case we change it */
dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
+ dspcntr &= ~DISPPLANE_ROTATE_180;
+
switch (fb->pixel_format) {
case DRM_FORMAT_C8:
dspcntr |= DISPPLANE_8BPP;
@@ -2549,8 +2568,6 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
else
dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
- I915_WRITE(reg, dspcntr);
-
linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
intel_crtc->dspaddr_offset =
intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
@@ -2558,6 +2575,21 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
fb->pitches[0]);
linear_offset -= intel_crtc->dspaddr_offset;
+ if (to_intel_plane(crtc->primary)->rotation == BIT(DRM_ROTATE_180)) {
+ dspcntr |= DISPPLANE_ROTATE_180;
+
+ if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) {
+ x += (intel_crtc->config.pipe_src_w - 1);
+ y += (intel_crtc->config.pipe_src_h - 1);
+ linear_offset +=
+ (intel_crtc->config.pipe_src_h - 1) *
+ fb->pitches[0] + (intel_crtc->config.pipe_src_w - 1) *
+ pixel_size;
+ }
+ }
+
+ I915_WRITE(reg, dspcntr);
+
DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n",
i915_gem_obj_ggtt_offset(obj), linear_offset, x, y,
fb->pitches[0]);
@@ -11324,10 +11356,57 @@ static void intel_plane_destroy(struct drm_plane *plane)
kfree(intel_plane);
}
+static int intel_primary_plane_set_property(struct drm_plane *plane,
+ struct drm_property *prop,
+ uint64_t val)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+ struct intel_crtc *intel_crtc = to_intel_crtc(plane->crtc);
+ struct drm_crtc *crtc = &intel_crtc->base;
+ uint64_t old_val;
+
+ if (prop == plane->rotation_property) {
+ /* exactly one rotation angle please */
+ if (hweight32(val & 0xf) != 1)
+ return -EINVAL;
+
+ old_val = intel_plane->rotation;
+ intel_plane->rotation = val;
+
+ if (intel_crtc->active && intel_crtc->primary_enabled) {
+ intel_crtc_wait_for_pending_flips(crtc);
+
+ /* FBC does not work on some platforms for rotated planes */
+ if (INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev)) {
+ if (dev_priv->fbc.plane == intel_crtc->plane &&
+ intel_plane->rotation != BIT(DRM_ROTATE_0))
+ intel_disable_fbc(dev);
+ /* If rotation was set earlier and new rotation is 0, we might
+ * have disabled fbc earlier. So update it now */
+ else if (intel_plane->rotation == BIT(DRM_ROTATE_0) &&
+ old_val != BIT(DRM_ROTATE_0))
+ intel_update_fbc(dev);
+ }
+
+ dev_priv->display.update_primary_plane(crtc,
+ crtc->primary->fb, 0, 0);
+
+ } else {
+ DRM_DEBUG_KMS("[CRTC:%d] is not active. Only rotation"
+ "property is updated\n", crtc->base.id);
+ }
+ }
+
+ return 0;
+}
+
static const struct drm_plane_funcs intel_primary_plane_funcs = {
.update_plane = intel_primary_plane_setplane,
.disable_plane = intel_primary_plane_disable,
.destroy = intel_plane_destroy,
+ .set_property = intel_primary_plane_set_property
};
static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
@@ -11345,6 +11424,7 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
primary->max_downscale = 1;
primary->pipe = pipe;
primary->plane = pipe;
+ primary->rotation = BIT(DRM_ROTATE_0);
if (HAS_FBC(dev) && INTEL_INFO(dev)->gen < 4)
primary->plane = !pipe;
@@ -11360,6 +11440,18 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
&intel_primary_plane_funcs,
intel_primary_formats, num_formats,
DRM_PLANE_TYPE_PRIMARY);
+ if (INTEL_INFO(dev)->gen >= 4) {
+ if (!primary->base.rotation_property)
+ primary->base.rotation_property =
+ drm_mode_create_rotation_property(dev,
+ BIT(DRM_ROTATE_0) |
+ BIT(DRM_ROTATE_180));
+ if (primary->base.rotation_property)
+ drm_object_attach_property(&primary->base.base,
+ primary->base.rotation_property,
+ primary->rotation);
+ }
+
return &primary->base;
}
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 2043c4b..bd6af91 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -562,6 +562,13 @@ void intel_update_fbc(struct drm_device *dev)
goto out_disable;
}
+ if (INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev) &&
+ to_intel_plane(crtc->primary)->rotation != BIT(DRM_ROTATE_0)) {
+ if (set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED_MODE))
+ DRM_DEBUG_KMS("Rotation unsupported, disabling\n");
+ goto out_disable;
+ }
+
/* If the kernel debugger is active, always disable compression */
if (in_dbg_master())
goto out_disable;
--
1.7.10.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [v2 11/11] drm: Resetting rotation property
2014-07-04 9:43 [v2 00/11] Support for 180 degree HW rotation sonika.jindal
` (9 preceding siblings ...)
2014-07-04 9:44 ` [v2 10/11] drm/i915: Add 180 degree primary plane rotation support sonika.jindal
@ 2014-07-04 9:44 ` sonika.jindal
2014-07-04 15:19 ` Damien Lespiau
2014-07-04 15:06 ` [v2 00/11] Support for 180 degree HW rotation Damien Lespiau
11 siblings, 1 reply; 19+ messages in thread
From: sonika.jindal @ 2014-07-04 9:44 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel
From: Sonika Jindal <sonika.jindal@intel.com>
Reset rotation property to 0 wherever applicable
v2: Also calling set_property of the plane to set the rotation in the plane
structure.
Cc: damien.lespiau@intel.com
Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
drivers/gpu/drm/drm_fb_helper.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index d5d8cea..30806b4 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -282,9 +282,23 @@ static bool restore_fbdev_mode(struct drm_fb_helper *fb_helper)
drm_warn_on_modeset_not_all_locked(dev);
- list_for_each_entry(plane, &dev->mode_config.plane_list, head)
+ list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+
+ if (plane->rotation_property) {
+ int ret = 0;
+ if (plane->funcs->set_property)
+ ret = plane->funcs->set_property(plane,
+ plane->rotation_property,
+ BIT(DRM_ROTATE_0));
+ if (!ret)
+ drm_object_property_set_value(&plane->base,
+ plane->rotation_property,
+ BIT(DRM_ROTATE_0));
+ }
+
if (plane->type != DRM_PLANE_TYPE_PRIMARY)
drm_plane_force_disable(plane);
+ }
for (i = 0; i < fb_helper->crtc_count; i++) {
struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [v2 10/11] drm/i915: Add 180 degree primary plane rotation support
2014-07-04 9:44 ` [v2 10/11] drm/i915: Add 180 degree primary plane rotation support sonika.jindal
@ 2014-07-04 14:58 ` Damien Lespiau
2014-07-06 8:08 ` Jindal, Sonika
2014-07-07 5:31 ` [PATCH] " sonika.jindal
0 siblings, 2 replies; 19+ messages in thread
From: Damien Lespiau @ 2014-07-04 14:58 UTC (permalink / raw)
To: sonika.jindal; +Cc: intel-gfx, Sagar Kamble, dri-devel
On Fri, Jul 04, 2014 at 03:14:02PM +0530, sonika.jindal@intel.com wrote:
> +static int intel_primary_plane_set_property(struct drm_plane *plane,
> + struct drm_property *prop,
> + uint64_t val)
> +{
> + struct drm_device *dev = plane->dev;
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + struct intel_plane *intel_plane = to_intel_plane(plane);
> + struct intel_crtc *intel_crtc = to_intel_crtc(plane->crtc);
> + struct drm_crtc *crtc = &intel_crtc->base;
> + uint64_t old_val;
> +
> + if (prop == plane->rotation_property) {
> + /* exactly one rotation angle please */
> + if (hweight32(val & 0xf) != 1)
> + return -EINVAL;
> +
> + old_val = intel_plane->rotation;
> + intel_plane->rotation = val;
> +
> + if (intel_crtc->active && intel_crtc->primary_enabled) {
> + intel_crtc_wait_for_pending_flips(crtc);
> +
> + /* FBC does not work on some platforms for rotated planes */
> + if (INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev)) {
> + if (dev_priv->fbc.plane == intel_crtc->plane &&
> + intel_plane->rotation != BIT(DRM_ROTATE_0))
> + intel_disable_fbc(dev);
> + /* If rotation was set earlier and new rotation is 0, we might
> + * have disabled fbc earlier. So update it now */
> + else if (intel_plane->rotation == BIT(DRM_ROTATE_0) &&
> + old_val != BIT(DRM_ROTATE_0))
> + intel_update_fbc(dev);
I see a intel_update_fbc() called with the struct_mutext lock elsewhere,
don't we need it here as well?
mutex_lock(&dev->struct_mutex);
intel_update_fbc(dev);
mutex_unlock(&dev->struct_mutex);
--
Damien
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [v2 00/11] Support for 180 degree HW rotation
2014-07-04 9:43 [v2 00/11] Support for 180 degree HW rotation sonika.jindal
` (10 preceding siblings ...)
2014-07-04 9:44 ` [v2 11/11] drm: Resetting rotation property sonika.jindal
@ 2014-07-04 15:06 ` Damien Lespiau
2014-07-06 8:11 ` Jindal, Sonika
11 siblings, 1 reply; 19+ messages in thread
From: Damien Lespiau @ 2014-07-04 15:06 UTC (permalink / raw)
To: sonika.jindal; +Cc: intel-gfx, dri-devel
On Fri, Jul 04, 2014 at 03:13:52PM +0530, sonika.jindal@intel.com wrote:
> From: Sonika Jindal <sonika.jindal@intel.com>
>
> Enables 180 degree rotation for sprite and primary planes.
> Updated the primary plane rotation support as per the new universal plane
> design.
>
> Most of these patches were already reviewed in intel-gfx in February 2014 thats
> why there is version history in few of them.
>
> v2: Moved rotation_property to drm_plane. Added updation of FBC when rotation is
> again set to 0.
>
> Testcase: kms_rotation_crc
> This igt can be extended for clipped rotation cases. Right it only tests 180
> degree rotation for sprite and primary plane with crc check.
>
>
> Sonika Jindal (2):
> drm/i915: Add 180 degree primary plane rotation support
> drm: Resetting rotation property
>
> Ville Syrjälä (9):
> drm: Move DRM_ROTATE bits out of omapdrm into drm_crtc.h
> drm: Add support_bits parameter to drm_property_create_bitmask()
> drm: Add drm_mode_create_rotation_property()
> drm/omap: Switch omapdrm over to drm_mode_create_rotation_property()
> drm: Add drm_rect rotation functions
> drm: Add drm_rotation_simplify()
> drm/i915: Add 180 degree sprite rotation support
> drm/i915: Make intel_plane_restore() return an error
> drm/i915: Add rotation property for sprites
Missing from this series, your two documentation patches (we need to
bundle things up as a entity that makes sense for one of the maintainers
to pick it up (either Dave or Daniel)).
--
Damien
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [v2 11/11] drm: Resetting rotation property
2014-07-04 9:44 ` [v2 11/11] drm: Resetting rotation property sonika.jindal
@ 2014-07-04 15:19 ` Damien Lespiau
0 siblings, 0 replies; 19+ messages in thread
From: Damien Lespiau @ 2014-07-04 15:19 UTC (permalink / raw)
To: sonika.jindal; +Cc: intel-gfx, dri-devel
On Fri, Jul 04, 2014 at 03:14:03PM +0530, sonika.jindal@intel.com wrote:
> From: Sonika Jindal <sonika.jindal@intel.com>
>
> Reset rotation property to 0 wherever applicable
>
> v2: Also calling set_property of the plane to set the rotation in the plane
> structure.
>
> Cc: damien.lespiau@intel.com
> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
Reviewed-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
> drivers/gpu/drm/drm_fb_helper.c | 16 +++++++++++++++-
> 1 file changed, 15 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
> index d5d8cea..30806b4 100644
> --- a/drivers/gpu/drm/drm_fb_helper.c
> +++ b/drivers/gpu/drm/drm_fb_helper.c
> @@ -282,9 +282,23 @@ static bool restore_fbdev_mode(struct drm_fb_helper *fb_helper)
>
> drm_warn_on_modeset_not_all_locked(dev);
>
> - list_for_each_entry(plane, &dev->mode_config.plane_list, head)
> + list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
> +
> + if (plane->rotation_property) {
> + int ret = 0;
> + if (plane->funcs->set_property)
> + ret = plane->funcs->set_property(plane,
> + plane->rotation_property,
> + BIT(DRM_ROTATE_0));
> + if (!ret)
> + drm_object_property_set_value(&plane->base,
> + plane->rotation_property,
> + BIT(DRM_ROTATE_0));
> + }
> +
> if (plane->type != DRM_PLANE_TYPE_PRIMARY)
> drm_plane_force_disable(plane);
> + }
>
> for (i = 0; i < fb_helper->crtc_count; i++) {
> struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set;
> --
> 1.7.10.4
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [v2 10/11] drm/i915: Add 180 degree primary plane rotation support
2014-07-04 14:58 ` Damien Lespiau
@ 2014-07-06 8:08 ` Jindal, Sonika
2014-07-07 5:31 ` [PATCH] " sonika.jindal
1 sibling, 0 replies; 19+ messages in thread
From: Jindal, Sonika @ 2014-07-06 8:08 UTC (permalink / raw)
To: Damien Lespiau; +Cc: intel-gfx, Sagar Kamble, dri-devel
On 7/4/2014 8:28 PM, Damien Lespiau wrote:
> On Fri, Jul 04, 2014 at 03:14:02PM +0530, sonika.jindal@intel.com wrote:
>> +static int intel_primary_plane_set_property(struct drm_plane *plane,
>> + struct drm_property *prop,
>> + uint64_t val)
>> +{
>> + struct drm_device *dev = plane->dev;
>> + struct drm_i915_private *dev_priv = dev->dev_private;
>> + struct intel_plane *intel_plane = to_intel_plane(plane);
>> + struct intel_crtc *intel_crtc = to_intel_crtc(plane->crtc);
>> + struct drm_crtc *crtc = &intel_crtc->base;
>> + uint64_t old_val;
>> +
>> + if (prop == plane->rotation_property) {
>> + /* exactly one rotation angle please */
>> + if (hweight32(val & 0xf) != 1)
>> + return -EINVAL;
>> +
>> + old_val = intel_plane->rotation;
>> + intel_plane->rotation = val;
>> +
>> + if (intel_crtc->active && intel_crtc->primary_enabled) {
>> + intel_crtc_wait_for_pending_flips(crtc);
>> +
>> + /* FBC does not work on some platforms for rotated planes */
>> + if (INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev)) {
>> + if (dev_priv->fbc.plane == intel_crtc->plane &&
>> + intel_plane->rotation != BIT(DRM_ROTATE_0))
>> + intel_disable_fbc(dev);
>> + /* If rotation was set earlier and new rotation is 0, we might
>> + * have disabled fbc earlier. So update it now */
>> + else if (intel_plane->rotation == BIT(DRM_ROTATE_0) &&
>> + old_val != BIT(DRM_ROTATE_0))
>> + intel_update_fbc(dev);
>
> I see a intel_update_fbc() called with the struct_mutext lock elsewhere,
> don't we need it here as well?
>
> mutex_lock(&dev->struct_mutex);
> intel_update_fbc(dev);
> mutex_unlock(&dev->struct_mutex);
>
Sure, I'l add that and post the patch.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [v2 00/11] Support for 180 degree HW rotation
2014-07-04 15:06 ` [v2 00/11] Support for 180 degree HW rotation Damien Lespiau
@ 2014-07-06 8:11 ` Jindal, Sonika
2014-07-07 13:38 ` Damien Lespiau
0 siblings, 1 reply; 19+ messages in thread
From: Jindal, Sonika @ 2014-07-06 8:11 UTC (permalink / raw)
To: Damien Lespiau; +Cc: intel-gfx, dri-devel
On 7/4/2014 8:36 PM, Damien Lespiau wrote:
> On Fri, Jul 04, 2014 at 03:13:52PM +0530, sonika.jindal@intel.com wrote:
>> From: Sonika Jindal <sonika.jindal@intel.com>
>>
>> Enables 180 degree rotation for sprite and primary planes.
>> Updated the primary plane rotation support as per the new universal plane
>> design.
>>
>> Most of these patches were already reviewed in intel-gfx in February 2014 thats
>> why there is version history in few of them.
>>
>> v2: Moved rotation_property to drm_plane. Added updation of FBC when rotation is
>> again set to 0.
>>
>> Testcase: kms_rotation_crc
>> This igt can be extended for clipped rotation cases. Right it only tests 180
>> degree rotation for sprite and primary plane with crc check.
>>
>>
>> Sonika Jindal (2):
>> drm/i915: Add 180 degree primary plane rotation support
>> drm: Resetting rotation property
>>
>> Ville Syrjälä (9):
>> drm: Move DRM_ROTATE bits out of omapdrm into drm_crtc.h
>> drm: Add support_bits parameter to drm_property_create_bitmask()
>> drm: Add drm_mode_create_rotation_property()
>> drm/omap: Switch omapdrm over to drm_mode_create_rotation_property()
>> drm: Add drm_rect rotation functions
>> drm: Add drm_rotation_simplify()
>> drm/i915: Add 180 degree sprite rotation support
>> drm/i915: Make intel_plane_restore() return an error
>> drm/i915: Add rotation property for sprites
>
> Missing from this series, your two documentation patches (we need to
> bundle things up as a entity that makes sense for one of the maintainers
> to pick it up (either Dave or Daniel)).
>
I was not aware that documentation patches should also be part of this.
Because I was asked to send the igt testcase separately I thought
documentation will also go separately. Documentation patches have also
got reviewed-by tags. What do you suggest? Should I send the patchset
again with documentation? Will Igt still be a separate post?
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH] drm/i915: Add 180 degree primary plane rotation support
2014-07-04 14:58 ` Damien Lespiau
2014-07-06 8:08 ` Jindal, Sonika
@ 2014-07-07 5:31 ` sonika.jindal
1 sibling, 0 replies; 19+ messages in thread
From: sonika.jindal @ 2014-07-07 5:31 UTC (permalink / raw)
To: intel-gfx; +Cc: Sagar Kamble, dri-devel, Daniel Vetter
From: Sonika Jindal <sonika.jindal@intel.com>
Primary planes support 180 degree rotation. Expose the feature
through rotation drm property.
v2: Calculating linear/tiled offsets based on pipe source width and
height. Added 180 degree rotation support in ironlake_update_plane.
v3: Checking if CRTC is active before issueing update_plane. Added
wait for vblank to make sure we dont overtake page flips. Disabling
FBC since it does not work with rotated planes.
v4: Updated rotation checks for pending flips, fbc disable. Creating
rotation property only for Gen4 onwards. Property resetting as part
of lastclose.
v5: Resetting property in i915_driver_lastclose properly for planes
and crtcs. Fixed linear offset calculation that was off by 1 w.r.t
width in i9xx_update_plane and ironlake_update_plane. Removed tab
based indentation and unnecessary braces in intel_crtc_set_property
and intel_update_fbc. FBC and flip related checks should be done only
for valid crtcs.
v6: Minor nits in FBC disable checks for comments in intel_crtc_set_property
and positioning the disable code in intel_update_fbc.
v7: In case rotation property on inactive crtc is updated, we return
successfully printing debug log as crtc is inactive and only property change
is preserved.
v8: update_plane is changed to update_primary_plane, crtc->fb is changed to
crtc->primary->fb and return value of update_primary_plane is ignored.
v9: added rotation property to primary plane instead of crtc. Removing reset
of rotation property from lastclose. rotation_property is moved to drm_plane,so
drm layer will take care of resetting.
v10: adding updation of fbc when rotation is set to 0.
v11: adding mutex locks for update_fbc. Allowing rotation only if value is
different than old one. Other minor cleanups.
Testcase: igt/kms_rotation_crc
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Sagar Kamble <sagar.a.kamble@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
drivers/gpu/drm/i915/i915_reg.h | 1 +
drivers/gpu/drm/i915/intel_display.c | 109 ++++++++++++++++++++++++++++++++--
drivers/gpu/drm/i915/intel_pm.c | 7 +++
3 files changed, 112 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index c70c804..c600d3b 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4087,6 +4087,7 @@ enum punit_power_well {
#define DISPPLANE_NO_LINE_DOUBLE 0
#define DISPPLANE_STEREO_POLARITY_FIRST 0
#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
+#define DISPPLANE_ROTATE_180 (1<<15)
#define DISPPLANE_TRICKLE_FEED_DISABLE (1<<14) /* Ironlake */
#define DISPPLANE_TILED (1<<10)
#define _DSPAADDR 0x70184
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 5e8e711..47ef1c8 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2414,7 +2414,9 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
unsigned long linear_offset;
u32 dspcntr;
u32 reg;
+ int pixel_size;
+ pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
intel_fb = to_intel_framebuffer(fb);
obj = intel_fb->obj;
@@ -2422,6 +2424,8 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
dspcntr = I915_READ(reg);
/* Mask out pixel format bits in case we change it */
dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
+ dspcntr &= ~DISPPLANE_ROTATE_180;
+
switch (fb->pixel_format) {
case DRM_FORMAT_C8:
dspcntr |= DISPPLANE_8BPP;
@@ -2463,8 +2467,6 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
if (IS_G4X(dev))
dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
- I915_WRITE(reg, dspcntr);
-
linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
if (INTEL_INFO(dev)->gen >= 4) {
@@ -2477,6 +2479,18 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
intel_crtc->dspaddr_offset = linear_offset;
}
+ if (to_intel_plane(crtc->primary)->rotation == BIT(DRM_ROTATE_180)) {
+ dspcntr |= DISPPLANE_ROTATE_180;
+
+ x += (intel_crtc->config.pipe_src_w - 1);
+ y += (intel_crtc->config.pipe_src_h - 1);
+ linear_offset += (intel_crtc->config.pipe_src_h - 1) *
+ fb->pitches[0] +
+ (intel_crtc->config.pipe_src_w - 1) * pixel_size;
+ }
+
+ I915_WRITE(reg, dspcntr);
+
DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n",
i915_gem_obj_ggtt_offset(obj), linear_offset, x, y,
fb->pitches[0]);
@@ -2487,7 +2501,8 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
I915_WRITE(DSPTILEOFF(plane), (y << 16) | x);
I915_WRITE(DSPLINOFF(plane), linear_offset);
} else
- I915_WRITE(DSPADDR(plane), i915_gem_obj_ggtt_offset(obj) + linear_offset);
+ I915_WRITE(DSPADDR(plane), i915_gem_obj_ggtt_offset(obj) +
+ linear_offset);
POSTING_READ(reg);
}
@@ -2504,7 +2519,9 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
unsigned long linear_offset;
u32 dspcntr;
u32 reg;
+ int pixel_size;
+ pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
intel_fb = to_intel_framebuffer(fb);
obj = intel_fb->obj;
@@ -2512,6 +2529,8 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
dspcntr = I915_READ(reg);
/* Mask out pixel format bits in case we change it */
dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
+ dspcntr &= ~DISPPLANE_ROTATE_180;
+
switch (fb->pixel_format) {
case DRM_FORMAT_C8:
dspcntr |= DISPPLANE_8BPP;
@@ -2549,8 +2568,6 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
else
dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
- I915_WRITE(reg, dspcntr);
-
linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
intel_crtc->dspaddr_offset =
intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
@@ -2558,6 +2575,21 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
fb->pitches[0]);
linear_offset -= intel_crtc->dspaddr_offset;
+ if (to_intel_plane(crtc->primary)->rotation == BIT(DRM_ROTATE_180)) {
+ dspcntr |= DISPPLANE_ROTATE_180;
+
+ if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) {
+ x += (intel_crtc->config.pipe_src_w - 1);
+ y += (intel_crtc->config.pipe_src_h - 1);
+ linear_offset +=
+ (intel_crtc->config.pipe_src_h - 1) *
+ fb->pitches[0] + (intel_crtc->config.pipe_src_w - 1) *
+ pixel_size;
+ }
+ }
+
+ I915_WRITE(reg, dspcntr);
+
DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n",
i915_gem_obj_ggtt_offset(obj), linear_offset, x, y,
fb->pitches[0]);
@@ -11324,10 +11356,64 @@ static void intel_plane_destroy(struct drm_plane *plane)
kfree(intel_plane);
}
+static int intel_primary_plane_set_property(struct drm_plane *plane,
+ struct drm_property *prop,
+ uint64_t val)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+ struct drm_crtc *crtc = plane->crtc;
+ struct intel_crtc *intel_crtc;
+ uint64_t old_val;
+
+ if (prop == plane->rotation_property) {
+ /* exactly one rotation angle please */
+ if (hweight32(val & 0xf) != 1)
+ return -EINVAL;
+
+ old_val = intel_plane->rotation;
+ intel_plane->rotation = val;
+
+ if (old_val == intel_plane->rotation)
+ return 0;
+
+ intel_crtc = to_intel_crtc(plane->crtc);
+
+ if (intel_crtc && intel_crtc->active && intel_crtc->primary_enabled) {
+ intel_crtc_wait_for_pending_flips(crtc);
+
+ /* FBC does not work on some platforms for rotated planes */
+ if (INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev)) {
+ if (dev_priv->fbc.plane == intel_crtc->plane &&
+ intel_plane->rotation != BIT(DRM_ROTATE_0))
+ intel_disable_fbc(dev);
+ /* If rotation was set earlier and new rotation is 0, we might
+ * have disabled fbc earlier. So update it now */
+ else if (intel_plane->rotation == BIT(DRM_ROTATE_0) &&
+ old_val != BIT(DRM_ROTATE_0)) {
+ mutex_lock(&dev->struct_mutex);
+ intel_update_fbc(dev);
+ mutex_unlock(&dev->struct_mutex);
+ }
+ }
+
+ dev_priv->display.update_primary_plane(crtc,
+ crtc->primary->fb, 0, 0);
+
+ } else {
+ DRM_DEBUG_KMS("[CRTC:%d] is not active. Only rotation"
+ "property is updated\n", crtc->base.id);
+ }
+ }
+ return 0;
+}
+
static const struct drm_plane_funcs intel_primary_plane_funcs = {
.update_plane = intel_primary_plane_setplane,
.disable_plane = intel_primary_plane_disable,
.destroy = intel_plane_destroy,
+ .set_property = intel_primary_plane_set_property
};
static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
@@ -11345,6 +11431,7 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
primary->max_downscale = 1;
primary->pipe = pipe;
primary->plane = pipe;
+ primary->rotation = BIT(DRM_ROTATE_0);
if (HAS_FBC(dev) && INTEL_INFO(dev)->gen < 4)
primary->plane = !pipe;
@@ -11360,6 +11447,18 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
&intel_primary_plane_funcs,
intel_primary_formats, num_formats,
DRM_PLANE_TYPE_PRIMARY);
+ if (INTEL_INFO(dev)->gen >= 4) {
+ if (!primary->base.rotation_property)
+ primary->base.rotation_property =
+ drm_mode_create_rotation_property(dev,
+ BIT(DRM_ROTATE_0) |
+ BIT(DRM_ROTATE_180));
+ if (primary->base.rotation_property)
+ drm_object_attach_property(&primary->base.base,
+ primary->base.rotation_property,
+ primary->rotation);
+ }
+
return &primary->base;
}
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 2043c4b..bd6af91 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -562,6 +562,13 @@ void intel_update_fbc(struct drm_device *dev)
goto out_disable;
}
+ if (INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev) &&
+ to_intel_plane(crtc->primary)->rotation != BIT(DRM_ROTATE_0)) {
+ if (set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED_MODE))
+ DRM_DEBUG_KMS("Rotation unsupported, disabling\n");
+ goto out_disable;
+ }
+
/* If the kernel debugger is active, always disable compression */
if (in_dbg_master())
goto out_disable;
--
1.7.10.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [v2 00/11] Support for 180 degree HW rotation
2014-07-06 8:11 ` Jindal, Sonika
@ 2014-07-07 13:38 ` Damien Lespiau
0 siblings, 0 replies; 19+ messages in thread
From: Damien Lespiau @ 2014-07-07 13:38 UTC (permalink / raw)
To: Jindal, Sonika; +Cc: intel-gfx, dri-devel
On Sun, Jul 06, 2014 at 01:41:12PM +0530, Jindal, Sonika wrote:
> >Missing from this series, your two documentation patches (we need to
> >bundle things up as a entity that makes sense for one of the maintainers
> >to pick it up (either Dave or Daniel)).
> >
> I was not aware that documentation patches should also be part of this.
> Because I was asked to send the igt testcase separately I thought
> documentation will also go separately. Documentation patches have
> also got reviewed-by tags. What do you suggest? Should I send the
> patchset again with documentation? Will Igt still be a separate
> post?
Please, resend the series entirely once again, with the latest review
tags added, the mutex locking around update_fbc() and the documentation
patches.
The reason with the documentation patches are part of this series is
that adding documentation is a requirement for adding new properties so
the whole DRM subsystem has a chance to converge towards a common set of
properties.
That series should also be annotated with a v3 in the cover letter.
Cheers,
--
Damien
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2014-07-07 13:38 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-07-04 9:43 [v2 00/11] Support for 180 degree HW rotation sonika.jindal
2014-07-04 9:43 ` [v2 01/11] drm: Move DRM_ROTATE bits out of omapdrm into drm_crtc.h sonika.jindal
2014-07-04 9:43 ` [v2 02/11] drm: Add support_bits parameter to drm_property_create_bitmask() sonika.jindal
2014-07-04 9:43 ` [v2 03/11] drm: Add drm_mode_create_rotation_property() sonika.jindal
2014-07-04 9:43 ` [v2 04/11] drm/omap: Switch omapdrm over to drm_mode_create_rotation_property() sonika.jindal
2014-07-04 9:43 ` [v2 05/11] drm: Add drm_rect rotation functions sonika.jindal
2014-07-04 9:43 ` [v2 06/11] drm: Add drm_rotation_simplify() sonika.jindal
2014-07-04 9:43 ` [v2 07/11] drm/i915: Add 180 degree sprite rotation support sonika.jindal
2014-07-04 9:44 ` [v2 08/11] drm/i915: Make intel_plane_restore() return an error sonika.jindal
2014-07-04 9:44 ` [v2 09/11] drm/i915: Add rotation property for sprites sonika.jindal
2014-07-04 9:44 ` [v2 10/11] drm/i915: Add 180 degree primary plane rotation support sonika.jindal
2014-07-04 14:58 ` Damien Lespiau
2014-07-06 8:08 ` Jindal, Sonika
2014-07-07 5:31 ` [PATCH] " sonika.jindal
2014-07-04 9:44 ` [v2 11/11] drm: Resetting rotation property sonika.jindal
2014-07-04 15:19 ` Damien Lespiau
2014-07-04 15:06 ` [v2 00/11] Support for 180 degree HW rotation Damien Lespiau
2014-07-06 8:11 ` Jindal, Sonika
2014-07-07 13:38 ` Damien Lespiau
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox