29,11 → 29,11 |
* registers; newer ones are much simpler and we can use the new DRM plane |
* support. |
*/ |
#include "drmP.h" |
#include "drm_crtc.h" |
#include "drm_fourcc.h" |
#include <drm/drmP.h> |
#include <drm/drm_crtc.h> |
#include <drm/drm_fourcc.h> |
#include "intel_drv.h" |
#include "i915_drm.h" |
#include <drm/i915_drm.h> |
#include "i915_drv.h" |
|
static void |
56,14 → 56,15 |
sprctl &= ~SPRITE_PIXFORMAT_MASK; |
sprctl &= ~SPRITE_RGB_ORDER_RGBX; |
sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK; |
sprctl &= ~SPRITE_TILED; |
|
switch (fb->pixel_format) { |
case DRM_FORMAT_XBGR8888: |
sprctl |= SPRITE_FORMAT_RGBX888; |
sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; |
pixel_size = 4; |
break; |
case DRM_FORMAT_XRGB8888: |
sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; |
sprctl |= SPRITE_FORMAT_RGBX888; |
pixel_size = 4; |
break; |
case DRM_FORMAT_YUYV: |
84,7 → 85,7 |
break; |
default: |
DRM_DEBUG_DRIVER("bad pixel format, assuming RGBX888\n"); |
sprctl |= DVS_FORMAT_RGBX888; |
sprctl |= SPRITE_FORMAT_RGBX888; |
pixel_size = 4; |
break; |
} |
95,7 → 96,6 |
/* must disable */ |
sprctl |= SPRITE_TRICKLE_FEED_DISABLE; |
sprctl |= SPRITE_ENABLE; |
sprctl |= SPRITE_DEST_KEY; |
|
/* Sizes are 0 based */ |
src_w--; |
111,15 → 111,19 |
* when scaling is disabled. |
*/ |
if (crtc_w != src_w || crtc_h != src_h) { |
if (!dev_priv->sprite_scaling_enabled) { |
dev_priv->sprite_scaling_enabled = true; |
sandybridge_update_wm(dev); |
intel_update_watermarks(dev); |
intel_wait_for_vblank(dev, pipe); |
} |
sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; |
} else { |
if (dev_priv->sprite_scaling_enabled) { |
dev_priv->sprite_scaling_enabled = false; |
/* potentially re-enable LP watermarks */ |
sandybridge_update_wm(dev); |
intel_update_watermarks(dev); |
} |
} |
|
I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]); |
I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x); |
134,7 → 138,7 |
I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w); |
I915_WRITE(SPRSCALE(pipe), sprscale); |
I915_WRITE(SPRCTL(pipe), sprctl); |
I915_WRITE(SPRSURF(pipe), obj->gtt_offset); |
I915_MODIFY_DISPBASE(SPRSURF(pipe), obj->gtt_offset); |
POSTING_READ(SPRSURF(pipe)); |
} |
|
150,8 → 154,11 |
/* Can't leave the scaler enabled... */ |
I915_WRITE(SPRSCALE(pipe), 0); |
/* Activate double buffered register update */ |
I915_WRITE(SPRSURF(pipe), 0); |
I915_MODIFY_DISPBASE(SPRSURF(pipe), 0); |
POSTING_READ(SPRSURF(pipe)); |
|
dev_priv->sprite_scaling_enabled = false; |
intel_update_watermarks(dev); |
} |
|
static int |
209,7 → 216,7 |
} |
|
static void |
snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, |
ilk_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, |
uint32_t x, uint32_t y, |
219,22 → 226,23 |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct intel_plane *intel_plane = to_intel_plane(plane); |
int pipe = intel_plane->pipe, pixel_size; |
u32 dvscntr, dvsscale = 0; |
u32 dvscntr, dvsscale; |
|
dvscntr = I915_READ(DVSCNTR(pipe)); |
|
/* Mask out pixel format bits in case we change it */ |
dvscntr &= ~DVS_PIXFORMAT_MASK; |
dvscntr &= ~DVS_RGB_ORDER_RGBX; |
dvscntr &= ~DVS_RGB_ORDER_XBGR; |
dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK; |
dvscntr &= ~DVS_TILED; |
|
switch (fb->pixel_format) { |
case DRM_FORMAT_XBGR8888: |
dvscntr |= DVS_FORMAT_RGBX888; |
dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR; |
pixel_size = 4; |
break; |
case DRM_FORMAT_XRGB8888: |
dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_RGBX; |
dvscntr |= DVS_FORMAT_RGBX888; |
pixel_size = 4; |
break; |
case DRM_FORMAT_YUYV: |
263,8 → 271,8 |
if (obj->tiling_mode != I915_TILING_NONE) |
dvscntr |= DVS_TILED; |
|
/* must disable */ |
dvscntr |= DVS_TRICKLE_FEED_DISABLE; |
if (IS_GEN6(dev)) |
dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */ |
dvscntr |= DVS_ENABLE; |
|
/* Sizes are 0 based */ |
275,7 → 283,8 |
|
intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size); |
|
if (crtc_w != src_w || crtc_h != src_h) |
dvsscale = 0; |
if (IS_GEN5(dev) || crtc_w != src_w || crtc_h != src_h) |
dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; |
|
I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]); |
291,12 → 300,12 |
I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); |
I915_WRITE(DVSSCALE(pipe), dvsscale); |
I915_WRITE(DVSCNTR(pipe), dvscntr); |
I915_WRITE(DVSSURF(pipe), obj->gtt_offset); |
I915_MODIFY_DISPBASE(DVSSURF(pipe), obj->gtt_offset); |
POSTING_READ(DVSSURF(pipe)); |
} |
|
static void |
snb_disable_plane(struct drm_plane *plane) |
ilk_disable_plane(struct drm_plane *plane) |
{ |
struct drm_device *dev = plane->dev; |
struct drm_i915_private *dev_priv = dev->dev_private; |
307,7 → 316,7 |
/* Disable the scaler */ |
I915_WRITE(DVSSCALE(pipe), 0); |
/* Flush double buffered register updates */ |
I915_WRITE(DVSSURF(pipe), 0); |
I915_MODIFY_DISPBASE(DVSSURF(pipe), 0); |
POSTING_READ(DVSSURF(pipe)); |
} |
|
319,6 → 328,12 |
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
int reg = DSPCNTR(intel_crtc->plane); |
|
if (!intel_crtc->primary_disabled) |
return; |
|
intel_crtc->primary_disabled = false; |
intel_update_fbc(dev); |
|
I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE); |
} |
|
330,11 → 345,17 |
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
int reg = DSPCNTR(intel_crtc->plane); |
|
if (intel_crtc->primary_disabled) |
return; |
|
I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE); |
|
intel_crtc->primary_disabled = true; |
intel_update_fbc(dev); |
} |
|
static int |
snb_update_colorkey(struct drm_plane *plane, |
ilk_update_colorkey(struct drm_plane *plane, |
struct drm_intel_sprite_colorkey *key) |
{ |
struct drm_device *dev = plane->dev; |
363,7 → 384,7 |
} |
|
static void |
snb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key) |
ilk_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key) |
{ |
struct drm_device *dev = plane->dev; |
struct drm_i915_private *dev_priv = dev->dev_private; |
411,6 → 432,9 |
|
old_obj = intel_plane->obj; |
|
src_w = src_w >> 16; |
src_h = src_h >> 16; |
|
/* Pipe must be running... */ |
if (!(I915_READ(PIPECONF(pipe)) & PIPECONF_ENABLE)) |
return -EINVAL; |
475,18 → 499,14 |
* Be sure to re-enable the primary before the sprite is no longer |
* covering it fully. |
*/ |
if (!disable_primary && intel_plane->primary_disabled) { |
if (!disable_primary) |
intel_enable_primary(crtc); |
intel_plane->primary_disabled = false; |
} |
|
intel_plane->update_plane(plane, fb, obj, crtc_x, crtc_y, |
crtc_w, crtc_h, x, y, src_w, src_h); |
|
if (disable_primary) { |
if (disable_primary) |
intel_disable_primary(crtc); |
intel_plane->primary_disabled = true; |
} |
|
/* Unpin old obj after new one is active to avoid ugliness */ |
if (old_obj) { |
501,7 → 521,7 |
intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe); |
mutex_lock(&dev->struct_mutex); |
} |
i915_gem_object_unpin(old_obj); |
intel_unpin_fb_obj(old_obj); |
} |
|
out_unlock: |
517,11 → 537,8 |
struct intel_plane *intel_plane = to_intel_plane(plane); |
int ret = 0; |
|
if (intel_plane->primary_disabled) { |
if (plane->crtc) |
intel_enable_primary(plane->crtc); |
intel_plane->primary_disabled = false; |
} |
|
intel_plane->disable_plane(plane); |
|
if (!intel_plane->obj) |
528,7 → 545,7 |
goto out; |
|
mutex_lock(&dev->struct_mutex); |
i915_gem_object_unpin(intel_plane->obj); |
intel_unpin_fb_obj(intel_plane->obj); |
intel_plane->obj = NULL; |
mutex_unlock(&dev->struct_mutex); |
out: |
548,14 → 565,13 |
struct drm_file *file_priv) |
{ |
struct drm_intel_sprite_colorkey *set = data; |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct drm_mode_object *obj; |
struct drm_plane *plane; |
struct intel_plane *intel_plane; |
int ret = 0; |
|
if (!dev_priv) |
return -EINVAL; |
// if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
// return -ENODEV; |
|
/* Make sure we don't try to enable both src & dest simultaneously */ |
if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) |
582,14 → 598,13 |
struct drm_file *file_priv) |
{ |
struct drm_intel_sprite_colorkey *get = data; |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct drm_mode_object *obj; |
struct drm_plane *plane; |
struct intel_plane *intel_plane; |
int ret = 0; |
|
if (!dev_priv) |
return -EINVAL; |
// if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
// return -ENODEV; |
|
mutex_lock(&dev->mode_config.mutex); |
|
614,6 → 629,14 |
.destroy = intel_destroy_plane, |
}; |
|
static uint32_t ilk_plane_formats[] = { |
DRM_FORMAT_XRGB8888, |
DRM_FORMAT_YUYV, |
DRM_FORMAT_YVYU, |
DRM_FORMAT_UYVY, |
DRM_FORMAT_VYUY, |
}; |
|
static uint32_t snb_plane_formats[] = { |
DRM_FORMAT_XBGR8888, |
DRM_FORMAT_XRGB8888, |
628,9 → 651,11 |
{ |
struct intel_plane *intel_plane; |
unsigned long possible_crtcs; |
const uint32_t *plane_formats; |
int num_plane_formats; |
int ret; |
|
if (!(IS_GEN6(dev) || IS_GEN7(dev))) |
if (INTEL_INFO(dev)->gen < 5) |
return -ENODEV; |
|
intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL); |
637,28 → 662,48 |
if (!intel_plane) |
return -ENOMEM; |
|
switch (INTEL_INFO(dev)->gen) { |
case 5: |
case 6: |
intel_plane->max_downscale = 16; |
intel_plane->update_plane = ilk_update_plane; |
intel_plane->disable_plane = ilk_disable_plane; |
intel_plane->update_colorkey = ilk_update_colorkey; |
intel_plane->get_colorkey = ilk_get_colorkey; |
|
if (IS_GEN6(dev)) { |
intel_plane->max_downscale = 16; |
intel_plane->update_plane = snb_update_plane; |
intel_plane->disable_plane = snb_disable_plane; |
intel_plane->update_colorkey = snb_update_colorkey; |
intel_plane->get_colorkey = snb_get_colorkey; |
} else if (IS_GEN7(dev)) { |
plane_formats = snb_plane_formats; |
num_plane_formats = ARRAY_SIZE(snb_plane_formats); |
} else { |
plane_formats = ilk_plane_formats; |
num_plane_formats = ARRAY_SIZE(ilk_plane_formats); |
} |
break; |
|
case 7: |
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: |
kfree(intel_plane); |
return -ENODEV; |
} |
|
intel_plane->pipe = pipe; |
possible_crtcs = (1 << pipe); |
ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs, |
&intel_plane_funcs, snb_plane_formats, |
ARRAY_SIZE(snb_plane_formats), false); |
&intel_plane_funcs, |
plane_formats, num_plane_formats, |
false); |
if (ret) |
kfree(intel_plane); |
|
return ret; |
} |
|