* [PATCH 1/1] drm/i915: Enabling plane rotation control through sysfs
@ 2014-01-24 13:48 sagar.a.kamble
2014-01-24 14:14 ` Ville Syrjälä
0 siblings, 1 reply; 4+ messages in thread
From: sagar.a.kamble @ 2014-01-24 13:48 UTC (permalink / raw)
To: intel-gfx; +Cc: Uma Shankar, Sagar Kamble
From: Sagar Kamble <sagar.a.kamble@intel.com>
This patch enables 180 degree rotation for primary and sprite planes
through sysfs interface.
Signed-off-by: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Sagar Kamble <sagar.a.kamble@intel.com>
---
drivers/gpu/drm/i915/i915_reg.h | 1 +
drivers/gpu/drm/i915/i915_sysfs.c | 124 +++++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/intel_display.c | 28 +++++++-
drivers/gpu/drm/i915/intel_drv.h | 8 +++
drivers/gpu/drm/i915/intel_sprite.c | 38 +++++++++--
5 files changed, 191 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 5d06ad6..92fa3d2 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3555,6 +3555,7 @@
#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
#define DISPPLANE_TRICKLE_FEED_DISABLE (1<<14) /* Ironlake */
#define DISPPLANE_TILED (1<<10)
+#define DISPPLANE_180_ROTATION_ENABLE (1<<15)
#define _DSPAADDR (dev_priv->info->display_mmio_offset + 0x70184)
#define _DSPASTRIDE (dev_priv->info->display_mmio_offset + 0x70188)
#define _DSPAPOS (dev_priv->info->display_mmio_offset + 0x7018C) /* reserved */
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index 33bcae3..12a214c 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -127,6 +127,122 @@ static struct attribute_group rc6_attr_group = {
};
#endif
+int i915_set_180_rotation(struct drm_device *dev,
+ struct i915_180_rotation *rotation)
+{
+ struct drm_mode_object *obj;
+ struct drm_crtc *crtc;
+ struct intel_crtc *intel_crtc;
+ struct drm_plane *plane;
+ struct intel_plane *intel_plane;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int ret = 0;
+
+ if (rotation->obj_type == DRM_MODE_OBJECT_PLANE) {
+ obj = drm_mode_object_find(dev, rotation->obj_id,
+ DRM_MODE_OBJECT_PLANE);
+ if (!obj) {
+ DRM_DEBUG_DRIVER("Unknown PLANE ID %d\n",
+ rotation->obj_id);
+ return -EINVAL;
+ }
+
+ plane = obj_to_plane(obj);
+ intel_plane = to_intel_plane(plane);
+ DRM_DEBUG_DRIVER("[SPRITE:%d] rotation set\n",
+ intel_plane->base.base.id);
+ intel_plane->rotate180 = (rotation->rotate & 0x1) ?
+ true : false;
+ ret = 1;
+ } else if (rotation->obj_type == DRM_MODE_OBJECT_CRTC) {
+ obj = drm_mode_object_find(dev, rotation->obj_id,
+ DRM_MODE_OBJECT_CRTC);
+ if (!obj) {
+ DRM_DEBUG_DRIVER("Unknown CRTC ID %d\n",
+ rotation->obj_id);
+ return -EINVAL;
+ }
+
+ crtc = obj_to_crtc(obj);
+ if (!crtc->enabled) {
+ DRM_DEBUG_DRIVER("[CRTC:%d] not active\n", crtc->base.id);
+ return ret;
+ }
+ DRM_DEBUG_DRIVER("[CRTC:%d] rotation set\n", crtc->base.id);
+ intel_crtc = to_intel_crtc(crtc);
+ intel_crtc->rotate180 = (rotation->rotate & 0x1) ?
+ true : false;
+ dev_priv->display.update_plane(crtc, crtc->fb, 0, 0);
+ ret = 1;
+ }
+
+ return ret;
+}
+
+static ssize_t
+i915_180_rotation_store(struct device *kdev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct drm_minor *minor = dev_to_drm_minor(kdev);
+ struct drm_device *dev = minor->dev;
+ struct i915_180_rotation rotation;
+ char buf1[30], id[11], type[11], val[2], format[18];
+ int len = 0, ret, no_of_tokens;
+ u32 rotate;
+
+ if (count == 0)
+ return -EINVAL;
+
+ /* Reset the string */
+ memset(buf1, 0, 30);
+ if (count > 0) {
+ if (count > sizeof(buf1) - 1)
+ return -EINVAL;
+ memcpy(buf1, buf, count);
+ }
+
+ scnprintf(format, sizeof(format), "%%%zus %%%zus %%%zus",
+ sizeof(id), sizeof(type), sizeof(val));
+
+ no_of_tokens = sscanf(buf1, format, id, type, val);
+ if (no_of_tokens < 3)
+ return len;
+
+ ret = kstrtou32(id, 0, &(rotation.obj_id));
+ if (ret)
+ return ret;
+
+ ret = kstrtou32(type, 0, &(rotation.obj_type));
+ if (ret)
+ return ret;
+
+ ret = kstrtou32(val, 0, &rotate);
+ if (ret)
+ return ret;
+
+ rotation.rotate = rotate ? true : false;
+
+ if (!i915_set_180_rotation(dev, &rotation))
+ return -EINVAL;
+
+ return count;
+}
+
+static DEVICE_ATTR(i915_180_rotation, S_IWUSR,
+ NULL,
+ i915_180_rotation_store);
+
+static struct attribute *display_attrs[] = {
+ &dev_attr_i915_180_rotation.attr,
+ NULL
+};
+
+static struct attribute_group display_attr_group = {
+ .name = "display",
+ .attrs = display_attrs
+};
+
static int l3_access_valid(struct drm_device *dev, loff_t offset)
{
if (!HAS_L3_DPF(dev))
@@ -568,6 +684,13 @@ void i915_setup_sysfs(struct drm_device *dev)
DRM_ERROR("RC6 residency sysfs setup failed\n");
}
#endif
+ if (INTEL_INFO(dev)->gen >= 6) {
+ ret = sysfs_create_group(&dev->primary->kdev->kobj,
+ &display_attr_group);
+ if (ret)
+ DRM_ERROR("Display sysfs setup failed\n");
+ }
+
if (HAS_L3_DPF(dev)) {
ret = device_create_bin_file(dev->primary->kdev, &dpf_attrs);
if (ret)
@@ -607,4 +730,5 @@ void i915_teardown_sysfs(struct drm_device *dev)
#ifdef CONFIG_PM
sysfs_unmerge_group(&dev->primary->kdev->kobj, &rc6_attr_group);
#endif
+ sysfs_unmerge_group(&dev->primary->kdev->kobj, &display_attr_group);
}
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index ec96002..5a1dc0b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -52,7 +52,6 @@ static void ironlake_pch_clock_get(struct intel_crtc *crtc,
static int intel_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
int x, int y, struct drm_framebuffer *old_fb);
-
typedef struct {
int min, max;
} intel_range_t;
@@ -2034,7 +2033,10 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
struct intel_framebuffer *intel_fb;
struct drm_i915_gem_object *obj;
int plane = intel_crtc->plane;
+ int pipe = intel_crtc->pipe;
unsigned long linear_offset;
+ bool rotate = false;
+ int pixel_size = 0;
u32 dspcntr;
u32 reg;
@@ -2047,6 +2049,7 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
return -EINVAL;
}
+ pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
intel_fb = to_intel_framebuffer(fb);
obj = intel_fb->obj;
@@ -2085,6 +2088,9 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
BUG();
}
+ if (intel_crtc->rotate180 && (pipe == 0))
+ rotate = true;
+
if (INTEL_INFO(dev)->gen >= 4) {
if (obj->tiling_mode != I915_TILING_NONE)
dspcntr |= DISPPLANE_TILED;
@@ -2095,6 +2101,11 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
if (IS_G4X(dev))
dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
+ if (rotate)
+ dspcntr |= DISPPLANE_180_ROTATION_ENABLE;
+ else
+ dspcntr &= ~DISPPLANE_180_ROTATION_ENABLE;
+
I915_WRITE(reg, dspcntr);
linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
@@ -2116,8 +2127,18 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
if (INTEL_INFO(dev)->gen >= 4) {
I915_MODIFY_DISPBASE(DSPSURF(plane),
i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset);
- I915_WRITE(DSPTILEOFF(plane), (y << 16) | x);
- I915_WRITE(DSPLINOFF(plane), linear_offset);
+ if (rotate) {
+ I915_WRITE(DSPTILEOFF(plane),
+ (((y + fb->height - 1) << 16) |
+ (x + fb->width - 1)));
+ I915_WRITE(DSPLINOFF(plane),
+ linear_offset +
+ (fb->height - 1) * fb->pitches[0] +
+ fb->width * pixel_size);
+ } else {
+ 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);
POSTING_READ(reg);
@@ -10317,6 +10338,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base;
dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base;
+ intel_crtc->rotate180 = false;
drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 7b3c209..1c199fd 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -327,10 +327,17 @@ struct intel_pipe_wm {
bool fbc_wm_enabled;
};
+struct i915_180_rotation {
+ u32 obj_id;
+ u32 obj_type;
+ bool rotate;
+};
+
struct intel_crtc {
struct drm_crtc base;
enum pipe pipe;
enum plane plane;
+ bool rotate180;
u8 lut_r[256], lut_g[256], lut_b[256];
/*
* Whether the crtc and the connected output pipeline is active. Implies
@@ -392,6 +399,7 @@ struct intel_plane {
struct drm_i915_gem_object *obj;
bool can_scale;
int max_downscale;
+ bool rotate180;
u32 lut_r[1024], lut_g[1024], lut_b[1024];
int crtc_x, crtc_y;
unsigned int crtc_w, crtc_h;
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index ed9fa7c..f3224fa 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -51,6 +51,7 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
int pipe = intel_plane->pipe;
int plane = intel_plane->plane;
u32 sprctl;
+ bool rotate = false;
unsigned long sprsurf_offset, linear_offset;
int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
@@ -118,6 +119,9 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
intel_update_sprite_watermarks(dplane, crtc, src_w, pixel_size, true,
src_w != crtc_w || src_h != crtc_h);
+ if (intel_plane->rotate180 && (pipe == 0))
+ rotate = true;
+
/* Sizes are 0 based */
src_w--;
src_h--;
@@ -132,14 +136,37 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
linear_offset -= sprsurf_offset;
I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]);
- I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x);
-
- if (obj->tiling_mode != I915_TILING_NONE)
- I915_WRITE(SPTILEOFF(pipe, plane), (y << 16) | x);
+ if (rotate)
+ I915_WRITE(SPPOS(pipe, plane),
+ ((crtc->hwmode.vdisplay - (crtc_y + crtc_h + 1))
+ << 16) |
+ (crtc->hwmode.hdisplay - (crtc_x + crtc_w + 1)));
else
- I915_WRITE(SPLINOFF(pipe, plane), linear_offset);
+ I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x);
+ if (obj->tiling_mode != I915_TILING_NONE) {
+ if (rotate)
+ I915_WRITE(SPTILEOFF(pipe, plane),
+ ((y + crtc_h) << 16) | (x + crtc_w));
+ else
+ I915_WRITE(SPTILEOFF(pipe, plane), (y << 16) | x);
+ } else {
+ if (rotate) {
+ int rot_linoff = linear_offset +
+ crtc_h * fb->pitches[0] +
+ (crtc_w + 1) * pixel_size;
+ I915_WRITE(SPLINOFF(pipe, plane), rot_linoff);
+
+ } else
+ I915_WRITE(SPLINOFF(pipe, plane), linear_offset);
+ }
I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w);
+
+ if (rotate)
+ sprctl |= DISPPLANE_180_ROTATION_ENABLE;
+ else
+ sprctl &= ~DISPPLANE_180_ROTATION_ENABLE;
+
I915_WRITE(SPCNTR(pipe, plane), sprctl);
I915_MODIFY_DISPBASE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) +
sprsurf_offset);
@@ -1141,6 +1168,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
intel_plane->pipe = pipe;
intel_plane->plane = plane;
+ intel_plane->rotate180 = false;
possible_crtcs = (1 << pipe);
ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs,
&intel_plane_funcs,
--
1.8.5
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH 1/1] drm/i915: Enabling plane rotation control through sysfs
2014-01-24 13:48 [PATCH 1/1] drm/i915: Enabling plane rotation control through sysfs sagar.a.kamble
@ 2014-01-24 14:14 ` Ville Syrjälä
2014-01-24 14:24 ` Ville Syrjälä
0 siblings, 1 reply; 4+ messages in thread
From: Ville Syrjälä @ 2014-01-24 14:14 UTC (permalink / raw)
To: sagar.a.kamble; +Cc: intel-gfx, Uma Shankar
On Fri, Jan 24, 2014 at 07:18:43PM +0530, sagar.a.kamble@intel.com wrote:
> From: Sagar Kamble <sagar.a.kamble@intel.com>
>
> This patch enables 180 degree rotation for primary and sprite planes
> through sysfs interface.
NAK.
See here for the right apporach:
http://lists.freedesktop.org/archives/intel-gfx/2013-September/033951.html
>
> Signed-off-by: Uma Shankar <uma.shankar@intel.com>
> Signed-off-by: Sagar Kamble <sagar.a.kamble@intel.com>
> ---
> drivers/gpu/drm/i915/i915_reg.h | 1 +
> drivers/gpu/drm/i915/i915_sysfs.c | 124 +++++++++++++++++++++++++++++++++++
> drivers/gpu/drm/i915/intel_display.c | 28 +++++++-
> drivers/gpu/drm/i915/intel_drv.h | 8 +++
> drivers/gpu/drm/i915/intel_sprite.c | 38 +++++++++--
> 5 files changed, 191 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 5d06ad6..92fa3d2 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -3555,6 +3555,7 @@
> #define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
> #define DISPPLANE_TRICKLE_FEED_DISABLE (1<<14) /* Ironlake */
> #define DISPPLANE_TILED (1<<10)
> +#define DISPPLANE_180_ROTATION_ENABLE (1<<15)
> #define _DSPAADDR (dev_priv->info->display_mmio_offset + 0x70184)
> #define _DSPASTRIDE (dev_priv->info->display_mmio_offset + 0x70188)
> #define _DSPAPOS (dev_priv->info->display_mmio_offset + 0x7018C) /* reserved */
> diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
> index 33bcae3..12a214c 100644
> --- a/drivers/gpu/drm/i915/i915_sysfs.c
> +++ b/drivers/gpu/drm/i915/i915_sysfs.c
> @@ -127,6 +127,122 @@ static struct attribute_group rc6_attr_group = {
> };
> #endif
>
> +int i915_set_180_rotation(struct drm_device *dev,
> + struct i915_180_rotation *rotation)
> +{
> + struct drm_mode_object *obj;
> + struct drm_crtc *crtc;
> + struct intel_crtc *intel_crtc;
> + struct drm_plane *plane;
> + struct intel_plane *intel_plane;
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + int ret = 0;
> +
> + if (rotation->obj_type == DRM_MODE_OBJECT_PLANE) {
> + obj = drm_mode_object_find(dev, rotation->obj_id,
> + DRM_MODE_OBJECT_PLANE);
> + if (!obj) {
> + DRM_DEBUG_DRIVER("Unknown PLANE ID %d\n",
> + rotation->obj_id);
> + return -EINVAL;
> + }
> +
> + plane = obj_to_plane(obj);
> + intel_plane = to_intel_plane(plane);
> + DRM_DEBUG_DRIVER("[SPRITE:%d] rotation set\n",
> + intel_plane->base.base.id);
> + intel_plane->rotate180 = (rotation->rotate & 0x1) ?
> + true : false;
> + ret = 1;
> + } else if (rotation->obj_type == DRM_MODE_OBJECT_CRTC) {
> + obj = drm_mode_object_find(dev, rotation->obj_id,
> + DRM_MODE_OBJECT_CRTC);
> + if (!obj) {
> + DRM_DEBUG_DRIVER("Unknown CRTC ID %d\n",
> + rotation->obj_id);
> + return -EINVAL;
> + }
> +
> + crtc = obj_to_crtc(obj);
> + if (!crtc->enabled) {
> + DRM_DEBUG_DRIVER("[CRTC:%d] not active\n", crtc->base.id);
> + return ret;
> + }
> + DRM_DEBUG_DRIVER("[CRTC:%d] rotation set\n", crtc->base.id);
> + intel_crtc = to_intel_crtc(crtc);
> + intel_crtc->rotate180 = (rotation->rotate & 0x1) ?
> + true : false;
> + dev_priv->display.update_plane(crtc, crtc->fb, 0, 0);
> + ret = 1;
> + }
> +
> + return ret;
> +}
> +
> +static ssize_t
> +i915_180_rotation_store(struct device *kdev,
> + struct device_attribute *attr,
> + const char *buf, size_t count)
> +{
> + struct drm_minor *minor = dev_to_drm_minor(kdev);
> + struct drm_device *dev = minor->dev;
> + struct i915_180_rotation rotation;
> + char buf1[30], id[11], type[11], val[2], format[18];
> + int len = 0, ret, no_of_tokens;
> + u32 rotate;
> +
> + if (count == 0)
> + return -EINVAL;
> +
> + /* Reset the string */
> + memset(buf1, 0, 30);
> + if (count > 0) {
> + if (count > sizeof(buf1) - 1)
> + return -EINVAL;
> + memcpy(buf1, buf, count);
> + }
> +
> + scnprintf(format, sizeof(format), "%%%zus %%%zus %%%zus",
> + sizeof(id), sizeof(type), sizeof(val));
> +
> + no_of_tokens = sscanf(buf1, format, id, type, val);
> + if (no_of_tokens < 3)
> + return len;
> +
> + ret = kstrtou32(id, 0, &(rotation.obj_id));
> + if (ret)
> + return ret;
> +
> + ret = kstrtou32(type, 0, &(rotation.obj_type));
> + if (ret)
> + return ret;
> +
> + ret = kstrtou32(val, 0, &rotate);
> + if (ret)
> + return ret;
> +
> + rotation.rotate = rotate ? true : false;
> +
> + if (!i915_set_180_rotation(dev, &rotation))
> + return -EINVAL;
> +
> + return count;
> +}
> +
> +static DEVICE_ATTR(i915_180_rotation, S_IWUSR,
> + NULL,
> + i915_180_rotation_store);
> +
> +static struct attribute *display_attrs[] = {
> + &dev_attr_i915_180_rotation.attr,
> + NULL
> +};
> +
> +static struct attribute_group display_attr_group = {
> + .name = "display",
> + .attrs = display_attrs
> +};
> +
> static int l3_access_valid(struct drm_device *dev, loff_t offset)
> {
> if (!HAS_L3_DPF(dev))
> @@ -568,6 +684,13 @@ void i915_setup_sysfs(struct drm_device *dev)
> DRM_ERROR("RC6 residency sysfs setup failed\n");
> }
> #endif
> + if (INTEL_INFO(dev)->gen >= 6) {
> + ret = sysfs_create_group(&dev->primary->kdev->kobj,
> + &display_attr_group);
> + if (ret)
> + DRM_ERROR("Display sysfs setup failed\n");
> + }
> +
> if (HAS_L3_DPF(dev)) {
> ret = device_create_bin_file(dev->primary->kdev, &dpf_attrs);
> if (ret)
> @@ -607,4 +730,5 @@ void i915_teardown_sysfs(struct drm_device *dev)
> #ifdef CONFIG_PM
> sysfs_unmerge_group(&dev->primary->kdev->kobj, &rc6_attr_group);
> #endif
> + sysfs_unmerge_group(&dev->primary->kdev->kobj, &display_attr_group);
> }
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index ec96002..5a1dc0b 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -52,7 +52,6 @@ static void ironlake_pch_clock_get(struct intel_crtc *crtc,
> static int intel_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
> int x, int y, struct drm_framebuffer *old_fb);
>
> -
> typedef struct {
> int min, max;
> } intel_range_t;
> @@ -2034,7 +2033,10 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
> struct intel_framebuffer *intel_fb;
> struct drm_i915_gem_object *obj;
> int plane = intel_crtc->plane;
> + int pipe = intel_crtc->pipe;
> unsigned long linear_offset;
> + bool rotate = false;
> + int pixel_size = 0;
> u32 dspcntr;
> u32 reg;
>
> @@ -2047,6 +2049,7 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
> return -EINVAL;
> }
>
> + pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
> intel_fb = to_intel_framebuffer(fb);
> obj = intel_fb->obj;
>
> @@ -2085,6 +2088,9 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
> BUG();
> }
>
> + if (intel_crtc->rotate180 && (pipe == 0))
> + rotate = true;
> +
> if (INTEL_INFO(dev)->gen >= 4) {
> if (obj->tiling_mode != I915_TILING_NONE)
> dspcntr |= DISPPLANE_TILED;
> @@ -2095,6 +2101,11 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
> if (IS_G4X(dev))
> dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
>
> + if (rotate)
> + dspcntr |= DISPPLANE_180_ROTATION_ENABLE;
> + else
> + dspcntr &= ~DISPPLANE_180_ROTATION_ENABLE;
> +
> I915_WRITE(reg, dspcntr);
>
> linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
> @@ -2116,8 +2127,18 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
> if (INTEL_INFO(dev)->gen >= 4) {
> I915_MODIFY_DISPBASE(DSPSURF(plane),
> i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset);
> - I915_WRITE(DSPTILEOFF(plane), (y << 16) | x);
> - I915_WRITE(DSPLINOFF(plane), linear_offset);
> + if (rotate) {
> + I915_WRITE(DSPTILEOFF(plane),
> + (((y + fb->height - 1) << 16) |
> + (x + fb->width - 1)));
> + I915_WRITE(DSPLINOFF(plane),
> + linear_offset +
> + (fb->height - 1) * fb->pitches[0] +
> + fb->width * pixel_size);
> + } else {
> + 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);
> POSTING_READ(reg);
> @@ -10317,6 +10338,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
> dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base;
> dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base;
>
> + intel_crtc->rotate180 = false;
> drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
> }
>
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 7b3c209..1c199fd 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -327,10 +327,17 @@ struct intel_pipe_wm {
> bool fbc_wm_enabled;
> };
>
> +struct i915_180_rotation {
> + u32 obj_id;
> + u32 obj_type;
> + bool rotate;
> +};
> +
> struct intel_crtc {
> struct drm_crtc base;
> enum pipe pipe;
> enum plane plane;
> + bool rotate180;
> u8 lut_r[256], lut_g[256], lut_b[256];
> /*
> * Whether the crtc and the connected output pipeline is active. Implies
> @@ -392,6 +399,7 @@ struct intel_plane {
> struct drm_i915_gem_object *obj;
> bool can_scale;
> int max_downscale;
> + bool rotate180;
> u32 lut_r[1024], lut_g[1024], lut_b[1024];
> int crtc_x, crtc_y;
> unsigned int crtc_w, crtc_h;
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index ed9fa7c..f3224fa 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -51,6 +51,7 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
> int pipe = intel_plane->pipe;
> int plane = intel_plane->plane;
> u32 sprctl;
> + bool rotate = false;
> unsigned long sprsurf_offset, linear_offset;
> int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
>
> @@ -118,6 +119,9 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
> intel_update_sprite_watermarks(dplane, crtc, src_w, pixel_size, true,
> src_w != crtc_w || src_h != crtc_h);
>
> + if (intel_plane->rotate180 && (pipe == 0))
> + rotate = true;
> +
> /* Sizes are 0 based */
> src_w--;
> src_h--;
> @@ -132,14 +136,37 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
> linear_offset -= sprsurf_offset;
>
> I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]);
> - I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x);
> -
> - if (obj->tiling_mode != I915_TILING_NONE)
> - I915_WRITE(SPTILEOFF(pipe, plane), (y << 16) | x);
> + if (rotate)
> + I915_WRITE(SPPOS(pipe, plane),
> + ((crtc->hwmode.vdisplay - (crtc_y + crtc_h + 1))
> + << 16) |
> + (crtc->hwmode.hdisplay - (crtc_x + crtc_w + 1)));
> else
> - I915_WRITE(SPLINOFF(pipe, plane), linear_offset);
> + I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x);
>
> + if (obj->tiling_mode != I915_TILING_NONE) {
> + if (rotate)
> + I915_WRITE(SPTILEOFF(pipe, plane),
> + ((y + crtc_h) << 16) | (x + crtc_w));
> + else
> + I915_WRITE(SPTILEOFF(pipe, plane), (y << 16) | x);
> + } else {
> + if (rotate) {
> + int rot_linoff = linear_offset +
> + crtc_h * fb->pitches[0] +
> + (crtc_w + 1) * pixel_size;
> + I915_WRITE(SPLINOFF(pipe, plane), rot_linoff);
> +
> + } else
> + I915_WRITE(SPLINOFF(pipe, plane), linear_offset);
> + }
> I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w);
> +
> + if (rotate)
> + sprctl |= DISPPLANE_180_ROTATION_ENABLE;
> + else
> + sprctl &= ~DISPPLANE_180_ROTATION_ENABLE;
> +
> I915_WRITE(SPCNTR(pipe, plane), sprctl);
> I915_MODIFY_DISPBASE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) +
> sprsurf_offset);
> @@ -1141,6 +1168,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
>
> intel_plane->pipe = pipe;
> intel_plane->plane = plane;
> + intel_plane->rotate180 = false;
> possible_crtcs = (1 << pipe);
> ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs,
> &intel_plane_funcs,
> --
> 1.8.5
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Ville Syrjälä
Intel OTC
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH 1/1] drm/i915: Enabling plane rotation control through sysfs
2014-01-24 14:14 ` Ville Syrjälä
@ 2014-01-24 14:24 ` Ville Syrjälä
2014-01-28 15:59 ` Ville Syrjälä
0 siblings, 1 reply; 4+ messages in thread
From: Ville Syrjälä @ 2014-01-24 14:24 UTC (permalink / raw)
To: sagar.a.kamble; +Cc: intel-gfx, Uma Shankar
On Fri, Jan 24, 2014 at 04:14:10PM +0200, Ville Syrjälä wrote:
> On Fri, Jan 24, 2014 at 07:18:43PM +0530, sagar.a.kamble@intel.com wrote:
> > From: Sagar Kamble <sagar.a.kamble@intel.com>
> >
> > This patch enables 180 degree rotation for primary and sprite planes
> > through sysfs interface.
>
> NAK.
>
> See here for the right apporach:
> http://lists.freedesktop.org/archives/intel-gfx/2013-September/033951.html
And BTW if you're really interested in getting this stuff in, we (Daniel
actually :) need tests in i-g-t. We have the display CRC stuff availalbe,
so fully automated tests are possible for this stuff. So this is
definitely one area where we're lacking manpower.
Some ideas for simple sprite tests:
- make sure it appears on the right spot on the screen
- make sure it doesn't appear when off screen
- make sure it clips correctly when partially off screen
- repeat everything w/ 180 degree rotation
One idea for a color key test:
- clear primary to solid color (or some fancier image)
- clear sprite to another color (or some fancier image)
- fill a small rect in the color key on the primary
- place the sprite on top of the color keyed are but make it slightly
bigger than the area, and make sure only the color keyed area shows
the sprite
So this would all involve rendering the reference images w/ software,
and then reproducing the expected result using the sprite, and making
sure it all matches up.
Finally come up with more tests as more properties get added (z order,
blending, etc.).
--
Ville Syrjälä
Intel OTC
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 1/1] drm/i915: Enabling plane rotation control through sysfs
2014-01-24 14:24 ` Ville Syrjälä
@ 2014-01-28 15:59 ` Ville Syrjälä
0 siblings, 0 replies; 4+ messages in thread
From: Ville Syrjälä @ 2014-01-28 15:59 UTC (permalink / raw)
To: sagar.a.kamble; +Cc: intel-gfx, Uma Shankar
On Fri, Jan 24, 2014 at 04:24:46PM +0200, Ville Syrjälä wrote:
> On Fri, Jan 24, 2014 at 04:14:10PM +0200, Ville Syrjälä wrote:
> > On Fri, Jan 24, 2014 at 07:18:43PM +0530, sagar.a.kamble@intel.com wrote:
> > > From: Sagar Kamble <sagar.a.kamble@intel.com>
> > >
> > > This patch enables 180 degree rotation for primary and sprite planes
> > > through sysfs interface.
> >
> > NAK.
> >
> > See here for the right apporach:
> > http://lists.freedesktop.org/archives/intel-gfx/2013-September/033951.html
>
> And BTW if you're really interested in getting this stuff in, we (Daniel
> actually :) need tests in i-g-t. We have the display CRC stuff availalbe,
> so fully automated tests are possible for this stuff. So this is
> definitely one area where we're lacking manpower.
>
> Some ideas for simple sprite tests:
> - make sure it appears on the right spot on the screen
> - make sure it doesn't appear when off screen
> - make sure it clips correctly when partially off screen
> - repeat everything w/ 180 degree rotation
Chris asked for tiled+sprites tests, so I figured I'd list a few more
things here for posterity:
- test both linear and tiled buffers
- test different pixel formats (dithering, csc, etc. might make this
a bit tricky)
- test panning inside a larger fb by adjusting the src
coordinates (overlaps a bit with the clipping tests, but
I think having separate tests for just panning w/o clipping
is still good)
--
Ville Syrjälä
Intel OTC
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2014-01-28 16:00 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-01-24 13:48 [PATCH 1/1] drm/i915: Enabling plane rotation control through sysfs sagar.a.kamble
2014-01-24 14:14 ` Ville Syrjälä
2014-01-24 14:24 ` Ville Syrjälä
2014-01-28 15:59 ` Ville Syrjälä
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox