On Fri, Mar 08, 2013 at 10:45:44AM -0800, Jesse Barnes wrote: > No constant alpha yet though, that needs a new ioctl and/or property to > get/set. > > v2: use drm_plane_format_cpp (Ville) > fix up vlv_disable_plane, remove IVB bits (Ville) > remove error path rework (Ville) > fix component order confusion (Ville) > clean up platform init (Ville) > use compute_offset_xtiled (Ville) > > Signed-off-by: Jesse Barnes <jbarnes at virtuousgeek.org> > --- > drivers/gpu/drm/i915/i915_dma.c | 4 + > drivers/gpu/drm/i915/i915_drv.h | 1 + > drivers/gpu/drm/i915/i915_reg.h | 57 +++++++++ > drivers/gpu/drm/i915/intel_display.c | 13 ++- > drivers/gpu/drm/i915/intel_drv.h | 3 +- > drivers/gpu/drm/i915/intel_sprite.c | 211 ++++++++++++++++++++++++++++++++-- > 6 files changed, 275 insertions(+), 14 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c > index e16099b..2ba68b0 100644 > --- a/drivers/gpu/drm/i915/i915_dma.c > +++ b/drivers/gpu/drm/i915/i915_dma.c > @@ -1637,6 +1637,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) > else > dev_priv->num_pipe = 1; > > + dev_priv->num_plane = 1; > + if (IS_VALLEYVIEW(dev)) > + dev_priv->num_plane = 2; > + > ret = drm_vblank_init(dev, dev_priv->num_pipe); > if (ret) > goto out_gem_unload; > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index ca6b215..2b4d9b6 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -914,6 +914,7 @@ typedef struct drm_i915_private { > > int num_pipe; > int num_pch_pll; > + int num_plane; > > unsigned long cfb_size; > unsigned int cfb_fb; > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index 4cf3ece..669a61c 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -3258,6 +3258,63 @@ > #define SPRGAMC(pipe) _PIPE(pipe, _SPRA_GAMC, _SPRB_GAMC) > #define SPRSURFLIVE(pipe) _PIPE(pipe, _SPRA_SURFLIVE, _SPRB_SURFLIVE) > > +#define _SPACNTR 0x72180 > +#define SP_ENABLE (1<<31) > +#define SP_GEAMMA_ENABLE (1<<30) > +#define SP_PIXFORMAT_MASK (0xf<<26) > +#define SP_FORMAT_YUV422 (0<<26) > +#define SP_FORMAT_BGR565 (5<<26) > +#define SP_FORMAT_BGRX8888 (6<<26) > +#define SP_FORMAT_BGRA8888 (7<<26) > +#define SP_FORMAT_RGBX1010102 (8<<26) > +#define SP_FORMAT_RGBA1010102 (9<<26) > +#define SP_FORMAT_RGBX8888 (0xe<<26) > +#define SP_FORMAT_RGBA8888 (0xf<<26) > +#define SP_SOURCE_KEY (1<<22) > +#define SP_YUV_BYTE_ORDER_MASK (3<<16) > +#define SP_YUV_ORDER_YUYV (0<<16) > +#define SP_YUV_ORDER_UYVY (1<<16) > +#define SP_YUV_ORDER_YVYU (2<<16) > +#define SP_YUV_ORDER_VYUY (3<<16) > +#define SP_TILED (1<<10) > +#define _SPALINOFF 0x72184 > +#define _SPASTRIDE 0x72188 > +#define _SPAPOS 0x7218c > +#define _SPASIZE 0x72190 > +#define _SPAKEYMINVAL 0x72194 > +#define _SPAKEYMSK 0x72198 > +#define _SPASURF 0x7219c > +#define _SPAKEYMAXVAL 0x721a0 > +#define _SPATILEOFF 0x721a4 > +#define _SPACONSTALPHA 0x721a8 > +#define _SPAGAMC 0x721f4 > + > +#define _SPBCNTR 0x72280 > +#define _SPBLINOFF 0x72284 > +#define _SPBSTRIDE 0x72288 > +#define _SPBPOS 0x7228c > +#define _SPBSIZE 0x72290 > +#define _SPBKEYMINVAL 0x72294 > +#define _SPBKEYMSK 0x72298 > +#define _SPBSURF 0x7229c > +#define _SPBKEYMAXVAL 0x722a0 > +#define _SPBTILEOFF 0x722a4 > +#define _SPBCONSTALPHA 0x722a8 > +#define _SPBGAMC 0x722f4 > + > +#define SPCNTR(pipe, plane) _PIPE(pipe * 2 + plane, _SPACNTR, _SPBCNTR) > +#define SPLINOFF(pipe, plane) _PIPE(pipe * 2 + plane, _SPALINOFF, _SPBLINOFF) > +#define SPSTRIDE(pipe, plane) _PIPE(pipe * 2 + plane, _SPASTRIDE, _SPBSTRIDE) > +#define SPPOS(pipe, plane) _PIPE(pipe * 2 + plane, _SPAPOS, _SPBPOS) > +#define SPSIZE(pipe, plane) _PIPE(pipe * 2 + plane, _SPASIZE, _SPBSIZE) > +#define SPKEYMINVAL(pipe, plane) _PIPE(pipe * 2 + plane, _SPAKEYMINVAL, _SPBKEYMINVAL) > +#define SPKEYMSK(pipe, plane) _PIPE(pipe * 2 + plane, _SPAKEYMSK, _SPBKEYMSK) > +#define SPSURF(pipe, plane) _PIPE(pipe * 2 + plane, _SPASURF, _SPBSURF) > +#define SPKEYMAXVAL(pipe, plane) _PIPE(pipe * 2 + plane, _SPAKEYMAXVAL, _SPBKEYMAXVAL) > +#define SPTILEOFF(pipe, plane) _PIPE(pipe * 2 + plane, _SPATILEOFF, _SPBTILEOFF) > +#define SPCONSTALPHA(pipe, plane) _PIPE(pipe * 2 + plane, _SPACONSTALPHA, _SPBCONSTALPHA) > +#define SPGAMC(pipe, plane) _PIPE(pipe * 2 + plane, _SPAGAMC, _SPBGAMC) > + > /* VBIOS regs */ > #define VGACNTRL 0x71400 > # define VGA_DISP_DISABLE (1 << 31) > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > index 502cb28..860bf7c 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -8508,6 +8508,8 @@ int intel_framebuffer_init(struct drm_device *dev, > case DRM_FORMAT_C8: > case DRM_FORMAT_RGB565: > case DRM_FORMAT_XRGB8888: > + case DRM_FORMAT_RGBX8888: > + case DRM_FORMAT_BGRX8888: > case DRM_FORMAT_ARGB8888: > break; > case DRM_FORMAT_XRGB1555: > @@ -8839,7 +8841,7 @@ void intel_modeset_init_hw(struct drm_device *dev) > void intel_modeset_init(struct drm_device *dev) > { > struct drm_i915_private *dev_priv = dev->dev_private; > - int i, ret; > + int i, j, ret; > > drm_mode_config_init(dev); > > @@ -8874,9 +8876,12 @@ void intel_modeset_init(struct drm_device *dev) > > for (i = 0; i < dev_priv->num_pipe; i++) { > intel_crtc_init(dev, i); > - ret = intel_plane_init(dev, i); > - if (ret) > - DRM_DEBUG_KMS("plane %d init failed: %d\n", i, ret); > + for (j = 0; j < dev_priv->num_plane; j++) { > + ret = intel_plane_init(dev, i, j); > + if (ret) > + DRM_DEBUG_KMS("pipe %d plane %d init failed: %d\n", > + i, j, ret); > + } > } > > intel_cpu_pll_init(dev); > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > index 010e998..494037d 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -242,6 +242,7 @@ struct intel_crtc { > > struct intel_plane { > struct drm_plane base; > + int plane; > enum pipe pipe; > struct drm_i915_gem_object *obj; > bool can_scale; > @@ -488,7 +489,7 @@ extern void intel_edp_link_config(struct intel_encoder *, int *, int *); > extern int intel_edp_target_clock(struct intel_encoder *, > struct drm_display_mode *mode); > extern bool intel_encoder_is_pch_edp(struct drm_encoder *encoder); > -extern int intel_plane_init(struct drm_device *dev, enum pipe pipe); > +extern int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane); > extern void intel_flush_display_plane(struct drm_i915_private *dev_priv, > enum plane plane); > > diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c > index d086e48..26fee2f 100644 > --- a/drivers/gpu/drm/i915/intel_sprite.c > +++ b/drivers/gpu/drm/i915/intel_sprite.c > @@ -37,6 +37,172 @@ > #include "i915_drv.h" > > static void > +vlv_update_plane(struct drm_plane *dplane, struct drm_framebuffer *fb, > + struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, > + unsigned int crtc_w, unsigned int crtc_h, > + uint32_t x, uint32_t y, > + uint32_t src_w, uint32_t src_h) > +{ > + struct drm_device *dev = dplane->dev; > + struct drm_i915_private *dev_priv = dev->dev_private; > + struct intel_plane *intel_plane = to_intel_plane(dplane); > + int pipe = intel_plane->pipe; > + int plane = intel_plane->plane; > + u32 sprctl; > + unsigned long sprsurf_offset, linear_offset; > + int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); > + > + sprctl = I915_READ(SPCNTR(pipe, plane)); > + > + /* Mask out pixel format bits in case we change it */ > + sprctl &= ~SP_PIXFORMAT_MASK; > + sprctl &= ~SP_YUV_BYTE_ORDER_MASK; > + sprctl &= ~SP_TILED; > + > + switch (fb->pixel_format) { > + case DRM_FORMAT_YUYV: > + sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV; > + break; > + case DRM_FORMAT_YVYU: > + sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU; > + break; > + case DRM_FORMAT_UYVY: > + sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY; > + break; > + case DRM_FORMAT_VYUY: > + sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY; > + break; The RGB formats still look wrong. I'll list here what I think they should be. > + case DRM_FORMAT_BGR565: DRM_FORMAT_RGB565 > + sprctl |= SP_FORMAT_BGR565; > + break; > + case DRM_FORMAT_BGRX8888: DRM_FORMAT_XRGB8888 > + sprctl |= SP_FORMAT_BGRX8888; > + break; > + case DRM_FORMAT_BGRA8888: DRM_FORMAT_ARGB8888 > + sprctl |= SP_FORMAT_BGRA8888; > + break; > + case DRM_FORMAT_RGBX1010102: DRM_FORMAT_XBGR2101010 > + sprctl |= SP_FORMAT_RGBX1010102; > + break; > + case DRM_FORMAT_RGBA1010102: DRM_FORMAT_ABGR2101010 > + sprctl |= SP_FORMAT_RGBA1010102; > + break; > + case DRM_FORMAT_RGBX8888: DRM_FORMAT_XBGR8888 > + sprctl |= SP_FORMAT_RGBX8888; > + break; > + case DRM_FORMAT_RGBA8888: DRM_FORMAT_ABGR8888 > + sprctl |= SP_FORMAT_RGBA8888; > + break; > + default: > + /* > + * If we get here one of the upper layers failed to filter > + * out the unsupported plane formats > + */ > + BUG(); > + break; > + } > + > + if (obj->tiling_mode != I915_TILING_NONE) > + sprctl |= SP_TILED; > + > + sprctl |= SP_ENABLE; > + > + /* Sizes are 0 based */ > + src_w--; > + src_h--; > + crtc_w--; > + crtc_h--; > + > + intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size); > + > + I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]); > + I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x); > + > + linear_offset = y * fb->pitches[0] + x * pixel_size; > + sprsurf_offset = intel_gen4_compute_offset_xtiled(&x, &y, pixel_size, > + fb->pitches[0]); It's called intel_gen4_compute_page_offset() these days. > + linear_offset -= sprsurf_offset; > + > + if (obj->tiling_mode != I915_TILING_NONE) > + I915_WRITE(SPTILEOFF(pipe, plane), (y << 16) | x); > + else > + I915_WRITE(SPLINOFF(pipe, plane), linear_offset); > + > + I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w); > + I915_WRITE(SPCNTR(pipe, plane), sprctl); > + I915_MODIFY_DISPBASE(SPSURF(pipe, plane), obj->gtt_offset + > + sprsurf_offset); > + POSTING_READ(SPSURF(pipe, plane)); > +} > + > +static void > +vlv_disable_plane(struct drm_plane *dplane) > +{ > + struct drm_device *dev = dplane->dev; > + struct drm_i915_private *dev_priv = dev->dev_private; > + struct intel_plane *intel_plane = to_intel_plane(dplane); > + int pipe = intel_plane->pipe; > + int plane = intel_plane->plane; > + > + I915_WRITE(SPCNTR(pipe, plane), I915_READ(SPCNTR(pipe, plane)) & > + ~SP_ENABLE); > + /* Activate double buffered register update */ > + I915_MODIFY_DISPBASE(SPSURF(pipe, plane), 0); > + POSTING_READ(SPSURF(pipe, plane)); > +} > + > +static int > +vlv_update_colorkey(struct drm_plane *dplane, > + struct drm_intel_sprite_colorkey *key) > +{ > + struct drm_device *dev = dplane->dev; > + struct drm_i915_private *dev_priv = dev->dev_private; > + struct intel_plane *intel_plane = to_intel_plane(dplane); > + int pipe = intel_plane->pipe; > + int plane = intel_plane->plane; > + u32 sprctl; > + > + if (key->flags & I915_SET_COLORKEY_DESTINATION) > + return -EINVAL; > + > + I915_WRITE(SPKEYMINVAL(pipe, plane), key->min_value); > + I915_WRITE(SPKEYMAXVAL(pipe, plane), key->max_value); > + I915_WRITE(SPKEYMSK(pipe, plane), key->channel_mask); > + > + sprctl = I915_READ(SPCNTR(pipe, plane)); > + sprctl &= ~SP_SOURCE_KEY; > + if (key->flags & I915_SET_COLORKEY_SOURCE) > + sprctl |= SP_SOURCE_KEY; > + I915_WRITE(SPCNTR(pipe, plane), sprctl); > + > + POSTING_READ(SPKEYMSK(pipe, plane)); > + > + return 0; > +} > + > +static void > +vlv_get_colorkey(struct drm_plane *dplane, > + struct drm_intel_sprite_colorkey *key) > +{ > + struct drm_device *dev = dplane->dev; > + struct drm_i915_private *dev_priv = dev->dev_private; > + struct intel_plane *intel_plane = to_intel_plane(dplane); > + int pipe = intel_plane->pipe; > + int plane = intel_plane->plane; > + u32 sprctl; > + > + key->min_value = I915_READ(SPKEYMINVAL(pipe, plane)); > + key->max_value = I915_READ(SPKEYMAXVAL(pipe, plane)); > + key->channel_mask = I915_READ(SPKEYMSK(pipe, plane)); > + > + sprctl = I915_READ(SPCNTR(pipe, plane)); > + if (sprctl & SP_SOURCE_KEY) > + key->flags = I915_SET_COLORKEY_SOURCE; > + else > + key->flags = I915_SET_COLORKEY_NONE; > +} > + > +static void > ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, > struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, > unsigned int crtc_w, unsigned int crtc_h, > @@ -670,8 +836,22 @@ static uint32_t snb_plane_formats[] = { > DRM_FORMAT_VYUY, > }; > > +static uint32_t vlv_plane_formats[] = { > + DRM_FORMAT_BGR565, > + DRM_FORMAT_ABGR8888, > + DRM_FORMAT_ARGB8888, > + DRM_FORMAT_XBGR8888, > + DRM_FORMAT_XRGB8888, > + DRM_FORMAT_XRGB2101010, > + DRM_FORMAT_ARGB2101010, > + DRM_FORMAT_YUYV, > + DRM_FORMAT_YVYU, > + DRM_FORMAT_UYVY, > + DRM_FORMAT_VYUY, > +}; > + > int > -intel_plane_init(struct drm_device *dev, enum pipe pipe) > +intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) > { > struct intel_plane *intel_plane; > unsigned long possible_crtcs; > @@ -710,14 +890,26 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe) > intel_plane->can_scale = false; > else > intel_plane->can_scale = true; > - intel_plane->max_downscale = 2; > - intel_plane->update_plane = ivb_update_plane; > - intel_plane->disable_plane = ivb_disable_plane; > - intel_plane->update_colorkey = ivb_update_colorkey; > - intel_plane->get_colorkey = ivb_get_colorkey; > - > - plane_formats = snb_plane_formats; > - num_plane_formats = ARRAY_SIZE(snb_plane_formats); > + > + if (IS_VALLEYVIEW(dev)) { > + intel_plane->max_downscale = 1; > + intel_plane->update_plane = vlv_update_plane; > + intel_plane->disable_plane = vlv_disable_plane; > + intel_plane->update_colorkey = vlv_update_colorkey; > + intel_plane->get_colorkey = vlv_get_colorkey; > + > + plane_formats = vlv_plane_formats; > + num_plane_formats = ARRAY_SIZE(vlv_plane_formats); > + } else { > + intel_plane->max_downscale = 2; > + intel_plane->update_plane = ivb_update_plane; > + intel_plane->disable_plane = ivb_disable_plane; > + intel_plane->update_colorkey = ivb_update_colorkey; > + intel_plane->get_colorkey = ivb_get_colorkey; > + > + plane_formats = snb_plane_formats; > + num_plane_formats = ARRAY_SIZE(snb_plane_formats); > + } > break; > > default: > @@ -726,6 +918,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe) > } > > intel_plane->pipe = pipe; > + intel_plane->plane = plane; > 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 at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Ville Syrj?l? Intel OTC