From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: sagar.a.kamble@intel.com
Cc: intel-gfx@lists.freedesktop.org, Uma Shankar <uma.shankar@intel.com>
Subject: Re: [PATCH 1/1] drm/i915: Enabling plane rotation control through sysfs
Date: Fri, 24 Jan 2014 16:14:10 +0200 [thread overview]
Message-ID: <20140124141410.GE9454@intel.com> (raw)
In-Reply-To: <1390571323-4885-1-git-send-email-sagar.a.kamble@intel.com>
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
next prev parent reply other threads:[~2014-01-24 14:14 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
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ä [this message]
2014-01-24 14:24 ` Ville Syrjälä
2014-01-28 15:59 ` Ville Syrjälä
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140124141410.GE9454@intel.com \
--to=ville.syrjala@linux.intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=sagar.a.kamble@intel.com \
--cc=uma.shankar@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.