Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 4559 → Rev 4560

/drivers/video/drm/i915/intel_sprite.c
104,6 → 104,12
break;
}
 
/*
* Enable gamma to match primary/cursor plane behaviour.
* FIXME should be user controllable via propertiesa.
*/
sprctl |= SP_GAMMA_ENABLE;
 
if (obj->tiling_mode != I915_TILING_NONE)
sprctl |= SP_TILED;
 
135,7 → 141,7
 
I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w);
I915_WRITE(SPCNTR(pipe, plane), sprctl);
I915_MODIFY_DISPBASE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) +
I915_WRITE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) +
sprsurf_offset);
POSTING_READ(SPSURF(pipe, plane));
}
152,7 → 158,7
I915_WRITE(SPCNTR(pipe, plane), I915_READ(SPCNTR(pipe, plane)) &
~SP_ENABLE);
/* Activate double buffered register update */
I915_MODIFY_DISPBASE(SPSURF(pipe, plane), 0);
I915_WRITE(SPSURF(pipe, plane), 0);
POSTING_READ(SPSURF(pipe, plane));
 
intel_update_sprite_watermarks(dplane, crtc, 0, 0, false, false);
224,7 → 230,6
u32 sprctl, sprscale = 0;
unsigned long sprsurf_offset, linear_offset;
int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
bool scaling_was_enabled = dev_priv->sprite_scaling_enabled;
 
sprctl = I915_READ(SPRCTL(pipe));
 
257,10 → 262,16
BUG();
}
 
/*
* Enable gamma to match primary/cursor plane behaviour.
* FIXME should be user controllable via propertiesa.
*/
sprctl |= SPRITE_GAMMA_ENABLE;
 
if (obj->tiling_mode != I915_TILING_NONE)
sprctl |= SPRITE_TILED;
 
if (IS_HASWELL(dev))
if (IS_HASWELL(dev) || IS_BROADWELL(dev))
sprctl &= ~SPRITE_TRICKLE_FEED_DISABLE;
else
sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
267,7 → 278,7
 
sprctl |= SPRITE_ENABLE;
 
if (IS_HASWELL(dev))
if (IS_HASWELL(dev) || IS_BROADWELL(dev))
sprctl |= SPRITE_PIPE_CSC_ENABLE;
 
intel_update_sprite_watermarks(plane, crtc, src_w, pixel_size, true,
279,21 → 290,8
crtc_w--;
crtc_h--;
 
/*
* IVB workaround: must disable low power watermarks for at least
* one frame before enabling scaling. LP watermarks can be re-enabled
* when scaling is disabled.
*/
if (crtc_w != src_w || crtc_h != src_h) {
dev_priv->sprite_scaling_enabled |= 1 << pipe;
 
if (!scaling_was_enabled) {
intel_update_watermarks(dev);
intel_wait_for_vblank(dev, pipe);
}
if (crtc_w != src_w || crtc_h != src_h)
sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
} else
dev_priv->sprite_scaling_enabled &= ~(1 << pipe);
 
I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]);
I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
306,7 → 304,7
 
/* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
* register */
if (IS_HASWELL(dev))
if (IS_HASWELL(dev) || IS_BROADWELL(dev))
I915_WRITE(SPROFFSET(pipe), (y << 16) | x);
else if (obj->tiling_mode != I915_TILING_NONE)
I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x);
317,13 → 315,9
if (intel_plane->can_scale)
I915_WRITE(SPRSCALE(pipe), sprscale);
I915_WRITE(SPRCTL(pipe), sprctl);
I915_MODIFY_DISPBASE(SPRSURF(pipe),
I915_WRITE(SPRSURF(pipe),
i915_gem_obj_ggtt_offset(obj) + sprsurf_offset);
POSTING_READ(SPRSURF(pipe));
 
/* potentially re-enable LP watermarks */
if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled)
intel_update_watermarks(dev);
}
 
static void
333,7 → 327,6
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_plane *intel_plane = to_intel_plane(plane);
int pipe = intel_plane->pipe;
bool scaling_was_enabled = dev_priv->sprite_scaling_enabled;
 
I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE);
/* Can't leave the scaler enabled... */
340,16 → 333,16
if (intel_plane->can_scale)
I915_WRITE(SPRSCALE(pipe), 0);
/* Activate double buffered register update */
I915_MODIFY_DISPBASE(SPRSURF(pipe), 0);
I915_WRITE(SPRSURF(pipe), 0);
POSTING_READ(SPRSURF(pipe));
 
dev_priv->sprite_scaling_enabled &= ~(1 << pipe);
/*
* Avoid underruns when disabling the sprite.
* FIXME remove once watermark updates are done properly.
*/
intel_wait_for_vblank(dev, pipe);
 
intel_update_sprite_watermarks(plane, crtc, 0, 0, false, false);
 
/* potentially re-enable LP watermarks */
if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled)
intel_update_watermarks(dev);
}
 
static int
453,6 → 446,12
BUG();
}
 
/*
* Enable gamma to match primary/cursor plane behaviour.
* FIXME should be user controllable via propertiesa.
*/
dvscntr |= DVS_GAMMA_ENABLE;
 
if (obj->tiling_mode != I915_TILING_NONE)
dvscntr |= DVS_TILED;
 
470,7 → 469,7
crtc_h--;
 
dvsscale = 0;
if (IS_GEN5(dev) || crtc_w != src_w || crtc_h != src_h)
if (crtc_w != src_w || crtc_h != src_h)
dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
 
I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]);
490,7 → 489,7
I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
I915_WRITE(DVSSCALE(pipe), dvsscale);
I915_WRITE(DVSCNTR(pipe), dvscntr);
I915_MODIFY_DISPBASE(DVSSURF(pipe),
I915_WRITE(DVSSURF(pipe),
i915_gem_obj_ggtt_offset(obj) + dvssurf_offset);
POSTING_READ(DVSSURF(pipe));
}
507,9 → 506,15
/* Disable the scaler */
I915_WRITE(DVSSCALE(pipe), 0);
/* Flush double buffered register updates */
I915_MODIFY_DISPBASE(DVSSURF(pipe), 0);
I915_WRITE(DVSSURF(pipe), 0);
POSTING_READ(DVSSURF(pipe));
 
/*
* Avoid underruns when disabling the sprite.
* FIXME remove once watermark updates are done properly.
*/
intel_wait_for_vblank(dev, pipe);
 
intel_update_sprite_watermarks(plane, crtc, 0, 0, false, false);
}
 
521,15 → 526,30
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int reg = DSPCNTR(intel_crtc->plane);
 
if (!intel_crtc->primary_disabled)
if (intel_crtc->primary_enabled)
return;
 
intel_crtc->primary_disabled = false;
intel_update_fbc(dev);
intel_crtc->primary_enabled = true;
 
I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE);
intel_flush_primary_plane(dev_priv, intel_crtc->plane);
 
/*
* FIXME IPS should be fine as long as one plane is
* enabled, but in practice it seems to have problems
* when going from primary only to sprite only and vice
* versa.
*/
if (intel_crtc->config.ips_enabled) {
intel_wait_for_vblank(dev, intel_crtc->pipe);
hsw_enable_ips(intel_crtc);
}
 
mutex_lock(&dev->struct_mutex);
intel_update_fbc(dev);
mutex_unlock(&dev->struct_mutex);
}
 
static void
intel_disable_primary(struct drm_crtc *crtc)
{
538,13 → 558,26
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int reg = DSPCNTR(intel_crtc->plane);
 
if (intel_crtc->primary_disabled)
if (!intel_crtc->primary_enabled)
return;
 
intel_crtc->primary_enabled = false;
 
mutex_lock(&dev->struct_mutex);
if (dev_priv->fbc.plane == intel_crtc->plane)
intel_disable_fbc(dev);
mutex_unlock(&dev->struct_mutex);
 
/*
* FIXME IPS should be fine as long as one plane is
* enabled, but in practice it seems to have problems
* when going from primary only to sprite only and vice
* versa.
*/
hsw_disable_ips(intel_crtc);
 
I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE);
 
intel_crtc->primary_disabled = true;
intel_update_fbc(dev);
intel_flush_primary_plane(dev_priv, intel_crtc->plane);
}
 
static int
615,6 → 648,15
}
}
 
static bool colorkey_enabled(struct intel_plane *intel_plane)
{
struct drm_intel_sprite_colorkey key;
 
intel_plane->get_colorkey(&intel_plane->base, &key);
 
return key.flags != I915_SET_COLORKEY_NONE;
}
 
static int
intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
struct drm_framebuffer *fb, int crtc_x, int crtc_y,
623,15 → 665,12
uint32_t src_w, uint32_t src_h)
{
struct drm_device *dev = plane->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_plane *intel_plane = to_intel_plane(plane);
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;
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
struct drm_i915_gem_object *obj = intel_fb->obj;
struct drm_i915_gem_object *old_obj = intel_plane->obj;
int ret;
bool disable_primary = false;
bool visible;
int hscale, vscale;
652,30 → 691,24
.y2 = crtc_y + crtc_h,
};
const struct drm_rect clip = {
.x2 = crtc->mode.hdisplay,
.y2 = crtc->mode.vdisplay,
.x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0,
.y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0,
};
const struct {
int crtc_x, crtc_y;
unsigned int crtc_w, crtc_h;
uint32_t src_x, src_y, src_w, src_h;
} orig = {
.crtc_x = crtc_x,
.crtc_y = crtc_y,
.crtc_w = crtc_w,
.crtc_h = crtc_h,
.src_x = src_x,
.src_y = src_y,
.src_w = src_w,
.src_h = src_h,
};
 
intel_fb = to_intel_framebuffer(fb);
obj = intel_fb->obj;
 
old_obj = intel_plane->obj;
 
intel_plane->crtc_x = crtc_x;
intel_plane->crtc_y = crtc_y;
intel_plane->crtc_w = crtc_w;
intel_plane->crtc_h = crtc_h;
intel_plane->src_x = src_x;
intel_plane->src_y = src_y;
intel_plane->src_w = src_w;
intel_plane->src_h = src_h;
 
/* Pipe must be running... */
if (!(I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_ENABLE)) {
DRM_DEBUG_KMS("Pipe disabled\n");
return -EINVAL;
}
 
/* Don't modify another pipe's plane */
if (intel_plane->pipe != intel_crtc->pipe) {
DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n");
809,8 → 842,8
* If the sprite is completely covering the primary plane,
* we can disable the primary and save power.
*/
disable_primary = drm_rect_equals(&dst, &clip);
WARN_ON(disable_primary && !visible);
disable_primary = drm_rect_equals(&dst, &clip) && !colorkey_enabled(intel_plane);
WARN_ON(disable_primary && !visible && intel_crtc->active);
 
mutex_lock(&dev->struct_mutex);
 
820,11 → 853,23
* the sprite planes only require 128KiB alignment and 32 PTE padding.
*/
ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
 
mutex_unlock(&dev->struct_mutex);
 
if (ret)
goto out_unlock;
return ret;
 
intel_plane->crtc_x = orig.crtc_x;
intel_plane->crtc_y = orig.crtc_y;
intel_plane->crtc_w = orig.crtc_w;
intel_plane->crtc_h = orig.crtc_h;
intel_plane->src_x = orig.src_x;
intel_plane->src_y = orig.src_y;
intel_plane->src_w = orig.src_w;
intel_plane->src_h = orig.src_h;
intel_plane->obj = obj;
 
if (intel_crtc->active) {
/*
* Be sure to re-enable the primary before the sprite is no longer
* covering it fully.
841,6 → 886,7
 
if (disable_primary)
intel_disable_primary(crtc);
}
 
/* Unpin old obj after new one is active to avoid ugliness */
if (old_obj) {
850,17 → 896,15
* wait for vblank to avoid ugliness, we only need to
* do the pin & ref bookkeeping.
*/
if (old_obj != obj) {
mutex_unlock(&dev->struct_mutex);
intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe);
if (old_obj != obj && intel_crtc->active)
intel_wait_for_vblank(dev, intel_crtc->pipe);
 
mutex_lock(&dev->struct_mutex);
}
intel_unpin_fb_obj(old_obj);
mutex_unlock(&dev->struct_mutex);
}
 
out_unlock:
mutex_unlock(&dev->struct_mutex);
return ret;
return 0;
}
 
static int
868,7 → 912,7
{
struct drm_device *dev = plane->dev;
struct intel_plane *intel_plane = to_intel_plane(plane);
int ret = 0;
struct intel_crtc *intel_crtc;
 
if (!plane->fb)
return 0;
876,23 → 920,27
if (WARN_ON(!plane->crtc))
return -EINVAL;
 
intel_crtc = to_intel_crtc(plane->crtc);
 
if (intel_crtc->active) {
intel_enable_primary(plane->crtc);
intel_plane->disable_plane(plane, plane->crtc);
}
 
if (!intel_plane->obj)
goto out;
 
if (intel_plane->obj) {
if (intel_crtc->active)
intel_wait_for_vblank(dev, intel_plane->pipe);
 
mutex_lock(&dev->struct_mutex);
intel_unpin_fb_obj(intel_plane->obj);
intel_plane->obj = NULL;
mutex_unlock(&dev->struct_mutex);
out:
 
return ret;
intel_plane->obj = NULL;
}
 
return 0;
}
 
static void intel_destroy_plane(struct drm_plane *plane)
{
struct intel_plane *intel_plane = to_intel_plane(plane);
921,7 → 969,7
 
obj = drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE);
if (!obj) {
ret = -EINVAL;
ret = -ENOENT;
goto out_unlock;
}
 
950,7 → 998,7
 
obj = drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE);
if (!obj) {
ret = -EINVAL;
ret = -ENOENT;
goto out_unlock;
}
 
1034,7 → 1082,7
if (INTEL_INFO(dev)->gen < 5)
return -ENODEV;
 
intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL);
intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL);
if (!intel_plane)
return -ENOMEM;
 
1058,6 → 1106,7
break;
 
case 7:
case 8:
if (IS_IVYBRIDGE(dev)) {
intel_plane->can_scale = true;
intel_plane->max_downscale = 2;