48,7 → 48,8 |
struct intel_plane *intel_plane = to_intel_plane(plane); |
int pipe = intel_plane->pipe; |
u32 sprctl, sprscale = 0; |
int pixel_size; |
unsigned long sprsurf_offset, linear_offset; |
int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
|
sprctl = I915_READ(SPRCTL(pipe)); |
|
61,33 → 62,24 |
switch (fb->pixel_format) { |
case DRM_FORMAT_XBGR8888: |
sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; |
pixel_size = 4; |
break; |
case DRM_FORMAT_XRGB8888: |
sprctl |= SPRITE_FORMAT_RGBX888; |
pixel_size = 4; |
break; |
case DRM_FORMAT_YUYV: |
sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV; |
pixel_size = 2; |
break; |
case DRM_FORMAT_YVYU: |
sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU; |
pixel_size = 2; |
break; |
case DRM_FORMAT_UYVY: |
sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY; |
pixel_size = 2; |
break; |
case DRM_FORMAT_VYUY: |
sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY; |
pixel_size = 2; |
break; |
default: |
DRM_DEBUG_DRIVER("bad pixel format, assuming RGBX888\n"); |
sprctl |= SPRITE_FORMAT_RGBX888; |
pixel_size = 4; |
break; |
BUG(); |
} |
|
if (obj->tiling_mode != I915_TILING_NONE) |
127,18 → 119,27 |
|
I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]); |
I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x); |
if (obj->tiling_mode != I915_TILING_NONE) { |
|
linear_offset = y * fb->pitches[0] + x * pixel_size; |
sprsurf_offset = |
intel_gen4_compute_offset_xtiled(&x, &y, |
pixel_size, fb->pitches[0]); |
linear_offset -= sprsurf_offset; |
|
/* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET |
* register */ |
if (IS_HASWELL(dev)) |
I915_WRITE(SPROFFSET(pipe), (y << 16) | x); |
else if (obj->tiling_mode != I915_TILING_NONE) |
I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x); |
} else { |
unsigned long offset; |
else |
I915_WRITE(SPRLINOFF(pipe), linear_offset); |
|
offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); |
I915_WRITE(SPRLINOFF(pipe), offset); |
} |
I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w); |
if (intel_plane->can_scale) |
I915_WRITE(SPRSCALE(pipe), sprscale); |
I915_WRITE(SPRCTL(pipe), sprctl); |
I915_MODIFY_DISPBASE(SPRSURF(pipe), obj->gtt_offset); |
I915_MODIFY_DISPBASE(SPRSURF(pipe), obj->gtt_offset + sprsurf_offset); |
POSTING_READ(SPRSURF(pipe)); |
} |
|
152,6 → 153,7 |
|
I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE); |
/* Can't leave the scaler enabled... */ |
if (intel_plane->can_scale) |
I915_WRITE(SPRSCALE(pipe), 0); |
/* Activate double buffered register update */ |
I915_MODIFY_DISPBASE(SPRSURF(pipe), 0); |
225,8 → 227,10 |
struct drm_device *dev = plane->dev; |
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; |
int pipe = intel_plane->pipe; |
unsigned long dvssurf_offset, linear_offset; |
u32 dvscntr, dvsscale; |
int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
|
dvscntr = I915_READ(DVSCNTR(pipe)); |
|
239,33 → 243,24 |
switch (fb->pixel_format) { |
case DRM_FORMAT_XBGR8888: |
dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR; |
pixel_size = 4; |
break; |
case DRM_FORMAT_XRGB8888: |
dvscntr |= DVS_FORMAT_RGBX888; |
pixel_size = 4; |
break; |
case DRM_FORMAT_YUYV: |
dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV; |
pixel_size = 2; |
break; |
case DRM_FORMAT_YVYU: |
dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU; |
pixel_size = 2; |
break; |
case DRM_FORMAT_UYVY: |
dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY; |
pixel_size = 2; |
break; |
case DRM_FORMAT_VYUY: |
dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY; |
pixel_size = 2; |
break; |
default: |
DRM_DEBUG_DRIVER("bad pixel format, assuming RGBX888\n"); |
dvscntr |= DVS_FORMAT_RGBX888; |
pixel_size = 4; |
break; |
BUG(); |
} |
|
if (obj->tiling_mode != I915_TILING_NONE) |
289,18 → 284,22 |
|
I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]); |
I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x); |
if (obj->tiling_mode != I915_TILING_NONE) { |
|
linear_offset = y * fb->pitches[0] + x * pixel_size; |
dvssurf_offset = |
intel_gen4_compute_offset_xtiled(&x, &y, |
pixel_size, fb->pitches[0]); |
linear_offset -= dvssurf_offset; |
|
if (obj->tiling_mode != I915_TILING_NONE) |
I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x); |
} else { |
unsigned long offset; |
else |
I915_WRITE(DVSLINOFF(pipe), linear_offset); |
|
offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); |
I915_WRITE(DVSLINOFF(pipe), offset); |
} |
I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); |
I915_WRITE(DVSSCALE(pipe), dvsscale); |
I915_WRITE(DVSCNTR(pipe), dvscntr); |
I915_MODIFY_DISPBASE(DVSSURF(pipe), obj->gtt_offset); |
I915_MODIFY_DISPBASE(DVSSURF(pipe), obj->gtt_offset + dvssurf_offset); |
POSTING_READ(DVSSURF(pipe)); |
} |
|
422,6 → 421,8 |
struct intel_framebuffer *intel_fb; |
struct drm_i915_gem_object *obj, *old_obj; |
int pipe = intel_plane->pipe; |
enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, |
pipe); |
int ret = 0; |
int x = src_x >> 16, y = src_y >> 16; |
int primary_w = crtc->mode.hdisplay, primary_h = crtc->mode.vdisplay; |
436,7 → 437,7 |
src_h = src_h >> 16; |
|
/* Pipe must be running... */ |
if (!(I915_READ(PIPECONF(pipe)) & PIPECONF_ENABLE)) |
if (!(I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_ENABLE)) |
return -EINVAL; |
|
if (crtc_x >= primary_w || crtc_y >= primary_h) |
446,6 → 447,15 |
if (intel_plane->pipe != intel_crtc->pipe) |
return -EINVAL; |
|
/* Sprite planes can be linear or x-tiled surfaces */ |
switch (obj->tiling_mode) { |
case I915_TILING_NONE: |
case I915_TILING_X: |
break; |
default: |
return -EINVAL; |
} |
|
/* |
* Clamp the width & height into the visible area. Note we don't |
* try to scale the source if part of the visible region is offscreen. |
473,6 → 483,12 |
goto out; |
|
/* |
* We may not have a scaler, eg. HSW does not have it any more |
*/ |
if (!intel_plane->can_scale && (crtc_w != src_w || crtc_h != src_h)) |
return -EINVAL; |
|
/* |
* We can take a larger source and scale it down, but |
* only so much... 16x is the max on SNB. |
*/ |
570,8 → 586,6 |
struct intel_plane *intel_plane; |
int ret = 0; |
|
// 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)) |
603,8 → 617,6 |
struct intel_plane *intel_plane; |
int ret = 0; |
|
// if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
// return -ENODEV; |
|
mutex_lock(&dev->mode_config.mutex); |
|
665,6 → 677,7 |
switch (INTEL_INFO(dev)->gen) { |
case 5: |
case 6: |
intel_plane->can_scale = true; |
intel_plane->max_downscale = 16; |
intel_plane->update_plane = ilk_update_plane; |
intel_plane->disable_plane = ilk_disable_plane; |
681,6 → 694,10 |
break; |
|
case 7: |
if (IS_HASWELL(dev) || IS_VALLEYVIEW(dev)) |
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; |