From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ville =?iso-8859-1?Q?Syrj=E4l=E4?= Subject: Re: [PATCH 1/1] drm/i915: Enabling plane rotation control through sysfs Date: Fri, 24 Jan 2014 16:14:10 +0200 Message-ID: <20140124141410.GE9454@intel.com> References: <1390571323-4885-1-git-send-email-sagar.a.kamble@intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Return-path: Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by gabe.freedesktop.org (Postfix) with ESMTP id 56BD2FB76D for ; Fri, 24 Jan 2014 06:14:15 -0800 (PST) Content-Disposition: inline In-Reply-To: <1390571323-4885-1-git-send-email-sagar.a.kamble@intel.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org To: sagar.a.kamble@intel.com Cc: intel-gfx@lists.freedesktop.org, Uma Shankar List-Id: intel-gfx@lists.freedesktop.org On Fri, Jan 24, 2014 at 07:18:43PM +0530, sagar.a.kamble@intel.com wrote: > From: Sagar Kamble > = > 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 > Signed-off-by: Sagar Kamble > --- > 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) /* res= erved */ > diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i91= 5_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 =3D { > }; > #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 =3D dev->dev_private; > + int ret =3D 0; > + > + if (rotation->obj_type =3D=3D DRM_MODE_OBJECT_PLANE) { > + obj =3D 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 =3D obj_to_plane(obj); > + intel_plane =3D to_intel_plane(plane); > + DRM_DEBUG_DRIVER("[SPRITE:%d] rotation set\n", > + intel_plane->base.base.id); > + intel_plane->rotate180 =3D (rotation->rotate & 0x1) ? > + true : false; > + ret =3D 1; > + } else if (rotation->obj_type =3D=3D DRM_MODE_OBJECT_CRTC) { > + obj =3D 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 =3D 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 =3D to_intel_crtc(crtc); > + intel_crtc->rotate180 =3D (rotation->rotate & 0x1) ? > + true : false; > + dev_priv->display.update_plane(crtc, crtc->fb, 0, 0); > + ret =3D 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 =3D dev_to_drm_minor(kdev); > + struct drm_device *dev =3D minor->dev; > + struct i915_180_rotation rotation; > + char buf1[30], id[11], type[11], val[2], format[18]; > + int len =3D 0, ret, no_of_tokens; > + u32 rotate; > + > + if (count =3D=3D 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 =3D sscanf(buf1, format, id, type, val); > + if (no_of_tokens < 3) > + return len; > + > + ret =3D kstrtou32(id, 0, &(rotation.obj_id)); > + if (ret) > + return ret; > + > + ret =3D kstrtou32(type, 0, &(rotation.obj_type)); > + if (ret) > + return ret; > + > + ret =3D kstrtou32(val, 0, &rotate); > + if (ret) > + return ret; > + > + rotation.rotate =3D 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[] =3D { > + &dev_attr_i915_180_rotation.attr, > + NULL > +}; > + > +static struct attribute_group display_attr_group =3D { > + .name =3D "display", > + .attrs =3D 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 >=3D 6) { > + ret =3D 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 =3D 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 *c= rtc, > 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 =3D intel_crtc->plane; > + int pipe =3D intel_crtc->pipe; > unsigned long linear_offset; > + bool rotate =3D false; > + int pixel_size =3D 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 =3D drm_format_plane_cpp(fb->pixel_format, 0); > intel_fb =3D to_intel_framebuffer(fb); > obj =3D 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 =3D=3D 0)) > + rotate =3D true; > + > if (INTEL_INFO(dev)->gen >=3D 4) { > if (obj->tiling_mode !=3D I915_TILING_NONE) > dspcntr |=3D DISPPLANE_TILED; > @@ -2095,6 +2101,11 @@ static int i9xx_update_plane(struct drm_crtc *crtc= , struct drm_framebuffer *fb, > if (IS_G4X(dev)) > dspcntr |=3D DISPPLANE_TRICKLE_FEED_DISABLE; > = > + if (rotate) > + dspcntr |=3D DISPPLANE_180_ROTATION_ENABLE; > + else > + dspcntr &=3D ~DISPPLANE_180_ROTATION_ENABLE; > + > I915_WRITE(reg, dspcntr); > = > linear_offset =3D 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 >=3D 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_offs= et); > POSTING_READ(reg); > @@ -10317,6 +10338,7 @@ static void intel_crtc_init(struct drm_device *de= v, int pipe) > dev_priv->plane_to_crtc_mapping[intel_crtc->plane] =3D &intel_crtc->bas= e; > dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] =3D &intel_crtc->base; > = > + intel_crtc->rotate180 =3D 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/inte= l_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/i= ntel_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_c= rtc *crtc, > int pipe =3D intel_plane->pipe; > int plane =3D intel_plane->plane; > u32 sprctl; > + bool rotate =3D false; > unsigned long sprsurf_offset, linear_offset; > int pixel_size =3D 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 !=3D crtc_w || src_h !=3D crtc_h); > = > + if (intel_plane->rotate180 && (pipe =3D=3D 0)) > + rotate =3D true; > + > /* Sizes are 0 based */ > src_w--; > src_h--; > @@ -132,14 +136,37 @@ vlv_update_plane(struct drm_plane *dplane, struct d= rm_crtc *crtc, > linear_offset -=3D sprsurf_offset; > = > I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]); > - I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x); > - > - if (obj->tiling_mode !=3D 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 !=3D 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 =3D 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 |=3D DISPPLANE_180_ROTATION_ENABLE; > + else > + sprctl &=3D ~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 =3D pipe; > intel_plane->plane =3D plane; > + intel_plane->rotate180 =3D false; > possible_crtcs =3D (1 << pipe); > ret =3D 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=E4l=E4 Intel OTC