Merge branch 'drm-kms-locking' of git://people.freedesktop.org/~danvet/drm-intel into drm-next
The aim of this locking rework is that ioctls which a compositor should be might call for every frame (set_cursor, page_flip, addfb, rmfb and getfb/create_handle) should not be able to block on kms background activities like output detection. And since each EDID read takes about 25ms (in the best case), that always means we'll drop at least one frame. The solution is to add per-crtc locking for these ioctls, and restrict background activities to only use the global lock. Change-the-world type of events (modeset, dpms, ...) need to grab all locks. Two tricky parts arose in the conversion: - A lot of current code assumes that a kms fb object can't disappear while holding the global lock, since the current code serializes fb destruction with it. Hence proper lifetime management using the already created refcounting for fbs need to be instantiated for all ioctls and interfaces/users. - The rmfb ioctl removes the to-be-deleted fb from all active users. But unconditionally taking the global kms lock to do so introduces an unacceptable potential stall point. And obviously changing the userspace abi isn't on the table, either. Hence this conversion opportunistically checks whether the rmfb ioctl holds the very last reference, which guarantees that the fb isn't in active use on any crtc or plane (thanks to the conversion to the new lifetime rules using proper refcounting). Only if this is not the case will the code go through the slowpath and grab all modeset locks. Sane compositors will never hit this path and so avoid the stall, but userspace relying on these semantics will also not break. All these cases are exercised by the newly added subtests for the i-g-t kms_flip, tested on a machine where a full detect cycle takes around 100 ms. It works, and no frames are dropped any more with these patches applied. kms_flip also contains a special case to exercise the above-describe rmfb slowpath. * 'drm-kms-locking' of git://people.freedesktop.org/~danvet/drm-intel: (335 commits) drm/fb_helper: check whether fbcon is bound drm/doc: updates for new framebuffer lifetime rules drm: don't hold crtc mutexes for connector ->detect callbacks drm: only grab the crtc lock for pageflips drm: optimize drm_framebuffer_remove drm/vmwgfx: add proper framebuffer refcounting drm/i915: dump refcount into framebuffer debugfs file drm: refcounting for crtc framebuffers drm: refcounting for sprite framebuffers drm: fb refcounting for dirtyfb_ioctl drm: don't take modeset locks in getfb ioctl drm: push modeset_lock_all into ->fb_create driver callbacks drm: nest modeset locks within fpriv->fbs_lock drm: reference framebuffers which are on the idr drm: revamp framebuffer cleanup interfaces drm: create drm_framebuffer_lookup drm: revamp locking around fb creation/destruction drm: only take the crtc lock for ->cursor_move drm: only take the crtc lock for ->cursor_set drm: add per-crtc locks ...
这个提交包含在:
@@ -1440,28 +1440,31 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
|
||||
ifbdev = dev_priv->fbdev;
|
||||
fb = to_intel_framebuffer(ifbdev->helper.fb);
|
||||
|
||||
seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, obj ",
|
||||
seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, refcount %d, obj ",
|
||||
fb->base.width,
|
||||
fb->base.height,
|
||||
fb->base.depth,
|
||||
fb->base.bits_per_pixel);
|
||||
fb->base.bits_per_pixel,
|
||||
atomic_read(&fb->base.refcount.refcount));
|
||||
describe_obj(m, fb->obj);
|
||||
seq_printf(m, "\n");
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
|
||||
mutex_lock(&dev->mode_config.fb_lock);
|
||||
list_for_each_entry(fb, &dev->mode_config.fb_list, base.head) {
|
||||
if (&fb->base == ifbdev->helper.fb)
|
||||
continue;
|
||||
|
||||
seq_printf(m, "user size: %d x %d, depth %d, %d bpp, obj ",
|
||||
seq_printf(m, "user size: %d x %d, depth %d, %d bpp, refcount %d, obj ",
|
||||
fb->base.width,
|
||||
fb->base.height,
|
||||
fb->base.depth,
|
||||
fb->base.bits_per_pixel);
|
||||
fb->base.bits_per_pixel,
|
||||
atomic_read(&fb->base.refcount.refcount));
|
||||
describe_obj(m, fb->obj);
|
||||
seq_printf(m, "\n");
|
||||
}
|
||||
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
mutex_unlock(&dev->mode_config.fb_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1720,7 +1720,8 @@ i915_gem_object_put_pages(struct drm_i915_gem_object *obj)
|
||||
}
|
||||
|
||||
static long
|
||||
i915_gem_purge(struct drm_i915_private *dev_priv, long target)
|
||||
__i915_gem_shrink(struct drm_i915_private *dev_priv, long target,
|
||||
bool purgeable_only)
|
||||
{
|
||||
struct drm_i915_gem_object *obj, *next;
|
||||
long count = 0;
|
||||
@@ -1728,7 +1729,7 @@ i915_gem_purge(struct drm_i915_private *dev_priv, long target)
|
||||
list_for_each_entry_safe(obj, next,
|
||||
&dev_priv->mm.unbound_list,
|
||||
gtt_list) {
|
||||
if (i915_gem_object_is_purgeable(obj) &&
|
||||
if ((i915_gem_object_is_purgeable(obj) || !purgeable_only) &&
|
||||
i915_gem_object_put_pages(obj) == 0) {
|
||||
count += obj->base.size >> PAGE_SHIFT;
|
||||
if (count >= target)
|
||||
@@ -1739,7 +1740,7 @@ i915_gem_purge(struct drm_i915_private *dev_priv, long target)
|
||||
list_for_each_entry_safe(obj, next,
|
||||
&dev_priv->mm.inactive_list,
|
||||
mm_list) {
|
||||
if (i915_gem_object_is_purgeable(obj) &&
|
||||
if ((i915_gem_object_is_purgeable(obj) || !purgeable_only) &&
|
||||
i915_gem_object_unbind(obj) == 0 &&
|
||||
i915_gem_object_put_pages(obj) == 0) {
|
||||
count += obj->base.size >> PAGE_SHIFT;
|
||||
@@ -1751,6 +1752,12 @@ i915_gem_purge(struct drm_i915_private *dev_priv, long target)
|
||||
return count;
|
||||
}
|
||||
|
||||
static long
|
||||
i915_gem_purge(struct drm_i915_private *dev_priv, long target)
|
||||
{
|
||||
return __i915_gem_shrink(dev_priv, target, true);
|
||||
}
|
||||
|
||||
static void
|
||||
i915_gem_shrink_all(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
@@ -3545,14 +3552,15 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
|
||||
goto out;
|
||||
}
|
||||
|
||||
obj->user_pin_count++;
|
||||
obj->pin_filp = file;
|
||||
if (obj->user_pin_count == 1) {
|
||||
if (obj->user_pin_count == 0) {
|
||||
ret = i915_gem_object_pin(obj, args->alignment, true, false);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
obj->user_pin_count++;
|
||||
obj->pin_filp = file;
|
||||
|
||||
/* XXX - flush the CPU caches for pinned objects
|
||||
* as the X server doesn't manage domains yet
|
||||
*/
|
||||
@@ -4381,6 +4389,9 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc)
|
||||
|
||||
if (nr_to_scan) {
|
||||
nr_to_scan -= i915_gem_purge(dev_priv, nr_to_scan);
|
||||
if (nr_to_scan > 0)
|
||||
nr_to_scan -= __i915_gem_shrink(dev_priv, nr_to_scan,
|
||||
false);
|
||||
if (nr_to_scan > 0)
|
||||
i915_gem_shrink_all(dev_priv);
|
||||
}
|
||||
@@ -4389,7 +4400,7 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc)
|
||||
list_for_each_entry(obj, &dev_priv->mm.unbound_list, gtt_list)
|
||||
if (obj->pages_pin_count == 0)
|
||||
cnt += obj->base.size >> PAGE_SHIFT;
|
||||
list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list)
|
||||
list_for_each_entry(obj, &dev_priv->mm.inactive_list, gtt_list)
|
||||
if (obj->pin_count == 0 && obj->pages_pin_count == 0)
|
||||
cnt += obj->base.size >> PAGE_SHIFT;
|
||||
|
||||
|
@@ -6415,6 +6415,8 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
|
||||
if (encoder->crtc) {
|
||||
crtc = encoder->crtc;
|
||||
|
||||
mutex_lock(&crtc->mutex);
|
||||
|
||||
old->dpms_mode = connector->dpms;
|
||||
old->load_detect_temp = false;
|
||||
|
||||
@@ -6444,6 +6446,7 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
|
||||
return false;
|
||||
}
|
||||
|
||||
mutex_lock(&crtc->mutex);
|
||||
intel_encoder->new_crtc = to_intel_crtc(crtc);
|
||||
to_intel_connector(connector)->new_encoder = intel_encoder;
|
||||
|
||||
@@ -6471,6 +6474,7 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
|
||||
DRM_DEBUG_KMS("reusing fbdev for load-detection framebuffer\n");
|
||||
if (IS_ERR(fb)) {
|
||||
DRM_DEBUG_KMS("failed to allocate framebuffer for load-detection\n");
|
||||
mutex_unlock(&crtc->mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -6478,6 +6482,7 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
|
||||
DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n");
|
||||
if (old->release_fb)
|
||||
old->release_fb->funcs->destroy(old->release_fb);
|
||||
mutex_unlock(&crtc->mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -6492,20 +6497,21 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
|
||||
struct intel_encoder *intel_encoder =
|
||||
intel_attached_encoder(connector);
|
||||
struct drm_encoder *encoder = &intel_encoder->base;
|
||||
struct drm_crtc *crtc = encoder->crtc;
|
||||
|
||||
DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
|
||||
connector->base.id, drm_get_connector_name(connector),
|
||||
encoder->base.id, drm_get_encoder_name(encoder));
|
||||
|
||||
if (old->load_detect_temp) {
|
||||
struct drm_crtc *crtc = encoder->crtc;
|
||||
|
||||
to_intel_connector(connector)->new_encoder = NULL;
|
||||
intel_encoder->new_crtc = NULL;
|
||||
intel_set_mode(crtc, NULL, 0, 0, NULL);
|
||||
|
||||
if (old->release_fb)
|
||||
old->release_fb->funcs->destroy(old->release_fb);
|
||||
if (old->release_fb) {
|
||||
drm_framebuffer_unregister_private(old->release_fb);
|
||||
drm_framebuffer_unreference(old->release_fb);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -6513,6 +6519,8 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
|
||||
/* Switch crtc and encoder back off if necessary */
|
||||
if (old->dpms_mode != DRM_MODE_DPMS_ON)
|
||||
connector->funcs->dpms(connector, old->dpms_mode);
|
||||
|
||||
mutex_unlock(&crtc->mutex);
|
||||
}
|
||||
|
||||
/* Returns the clock of the currently programmed mode of the given pipe. */
|
||||
@@ -8318,19 +8326,30 @@ int intel_framebuffer_init(struct drm_device *dev,
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (obj->tiling_mode == I915_TILING_Y)
|
||||
if (obj->tiling_mode == I915_TILING_Y) {
|
||||
DRM_DEBUG("hardware does not support tiling Y\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (mode_cmd->pitches[0] & 63)
|
||||
if (mode_cmd->pitches[0] & 63) {
|
||||
DRM_DEBUG("pitch (%d) must be at least 64 byte aligned\n",
|
||||
mode_cmd->pitches[0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* FIXME <= Gen4 stride limits are bit unclear */
|
||||
if (mode_cmd->pitches[0] > 32768)
|
||||
if (mode_cmd->pitches[0] > 32768) {
|
||||
DRM_DEBUG("pitch (%d) must be at less than 32768\n",
|
||||
mode_cmd->pitches[0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (obj->tiling_mode != I915_TILING_NONE &&
|
||||
mode_cmd->pitches[0] != obj->stride)
|
||||
mode_cmd->pitches[0] != obj->stride) {
|
||||
DRM_DEBUG("pitch (%d) must match tiling stride (%d)\n",
|
||||
mode_cmd->pitches[0], obj->stride);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Reject formats not supported by any plane early. */
|
||||
switch (mode_cmd->pixel_format) {
|
||||
@@ -8341,8 +8360,10 @@ int intel_framebuffer_init(struct drm_device *dev,
|
||||
break;
|
||||
case DRM_FORMAT_XRGB1555:
|
||||
case DRM_FORMAT_ARGB1555:
|
||||
if (INTEL_INFO(dev)->gen > 3)
|
||||
if (INTEL_INFO(dev)->gen > 3) {
|
||||
DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format);
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case DRM_FORMAT_XBGR8888:
|
||||
case DRM_FORMAT_ABGR8888:
|
||||
@@ -8350,18 +8371,22 @@ int intel_framebuffer_init(struct drm_device *dev,
|
||||
case DRM_FORMAT_ARGB2101010:
|
||||
case DRM_FORMAT_XBGR2101010:
|
||||
case DRM_FORMAT_ABGR2101010:
|
||||
if (INTEL_INFO(dev)->gen < 4)
|
||||
if (INTEL_INFO(dev)->gen < 4) {
|
||||
DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format);
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case DRM_FORMAT_YUYV:
|
||||
case DRM_FORMAT_UYVY:
|
||||
case DRM_FORMAT_YVYU:
|
||||
case DRM_FORMAT_VYUY:
|
||||
if (INTEL_INFO(dev)->gen < 6)
|
||||
if (INTEL_INFO(dev)->gen < 5) {
|
||||
DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format);
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DRM_DEBUG_KMS("unsupported pixel format 0x%08x\n", mode_cmd->pixel_format);
|
||||
DRM_DEBUG("unsupported pixel format 0x%08x\n", mode_cmd->pixel_format);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -8369,14 +8394,15 @@ int intel_framebuffer_init(struct drm_device *dev,
|
||||
if (mode_cmd->offsets[0] != 0)
|
||||
return -EINVAL;
|
||||
|
||||
drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd);
|
||||
intel_fb->obj = obj;
|
||||
|
||||
ret = drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs);
|
||||
if (ret) {
|
||||
DRM_ERROR("framebuffer init failed %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd);
|
||||
intel_fb->obj = obj;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -1101,6 +1101,8 @@ static void ironlake_panel_vdd_off_sync(struct intel_dp *intel_dp)
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 pp;
|
||||
|
||||
WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
|
||||
|
||||
if (!intel_dp->want_panel_vdd && ironlake_edp_have_panel_vdd(intel_dp)) {
|
||||
pp = ironlake_get_pp_control(dev_priv);
|
||||
pp &= ~EDP_FORCE_VDD;
|
||||
|
@@ -221,6 +221,7 @@ static void intel_fbdev_destroy(struct drm_device *dev,
|
||||
|
||||
drm_fb_helper_fini(&ifbdev->helper);
|
||||
|
||||
drm_framebuffer_unregister_private(&ifb->base);
|
||||
drm_framebuffer_cleanup(&ifb->base);
|
||||
if (ifb->obj) {
|
||||
drm_gem_object_unreference_unlocked(&ifb->obj->base);
|
||||
@@ -297,7 +298,7 @@ void intel_fb_restore_mode(struct drm_device *dev)
|
||||
struct drm_mode_config *config = &dev->mode_config;
|
||||
struct drm_plane *plane;
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
drm_modeset_lock_all(dev);
|
||||
|
||||
ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper);
|
||||
if (ret)
|
||||
@@ -307,5 +308,5 @@ void intel_fb_restore_mode(struct drm_device *dev)
|
||||
list_for_each_entry(plane, &config->plane_list, head)
|
||||
plane->funcs->disable_plane(plane);
|
||||
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
drm_modeset_unlock_all(dev);
|
||||
}
|
||||
|
@@ -586,9 +586,9 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
|
||||
|
||||
dev_priv->modeset_on_lid = 0;
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
drm_modeset_lock_all(dev);
|
||||
intel_modeset_setup_hw_state(dev, true);
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
drm_modeset_unlock_all(dev);
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
@@ -828,14 +828,6 @@ static const struct dmi_system_id intel_no_lvds[] = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "MS-7469"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = intel_no_lvds_dmi_callback,
|
||||
.ident = "ZOTAC ZBOXSD-ID12/ID13",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "ZOTAC"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "ZBOXSD-ID12/ID13"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = intel_no_lvds_dmi_callback,
|
||||
.ident = "Gigabyte GA-D525TUD",
|
||||
|
@@ -1045,13 +1045,13 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
|
||||
}
|
||||
|
||||
if (!(put_image_rec->flags & I915_OVERLAY_ENABLE)) {
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
drm_modeset_lock_all(dev);
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
|
||||
ret = intel_overlay_switch_off(overlay);
|
||||
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
drm_modeset_unlock_all(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1075,7 +1075,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
drm_modeset_lock_all(dev);
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
|
||||
if (new_bo->tiling_mode) {
|
||||
@@ -1157,7 +1157,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
|
||||
goto out_unlock;
|
||||
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
drm_modeset_unlock_all(dev);
|
||||
|
||||
kfree(params);
|
||||
|
||||
@@ -1165,7 +1165,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
drm_modeset_unlock_all(dev);
|
||||
drm_gem_object_unreference_unlocked(&new_bo->base);
|
||||
out_free:
|
||||
kfree(params);
|
||||
@@ -1241,7 +1241,7 @@ int intel_overlay_attrs(struct drm_device *dev, void *data,
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
drm_modeset_lock_all(dev);
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
|
||||
ret = -EINVAL;
|
||||
@@ -1307,7 +1307,7 @@ int intel_overlay_attrs(struct drm_device *dev, void *data,
|
||||
ret = 0;
|
||||
out_unlock:
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
drm_modeset_unlock_all(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@@ -44,6 +44,14 @@
|
||||
* i915.i915_enable_fbc parameter
|
||||
*/
|
||||
|
||||
static bool intel_crtc_active(struct drm_crtc *crtc)
|
||||
{
|
||||
/* Be paranoid as we can arrive here with only partial
|
||||
* state retrieved from the hardware during setup.
|
||||
*/
|
||||
return to_intel_crtc(crtc)->active && crtc->fb && crtc->mode.clock;
|
||||
}
|
||||
|
||||
static void i8xx_disable_fbc(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
@@ -405,9 +413,8 @@ void intel_update_fbc(struct drm_device *dev)
|
||||
* - going to an unsupported config (interlace, pixel multiply, etc.)
|
||||
*/
|
||||
list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) {
|
||||
if (to_intel_crtc(tmp_crtc)->active &&
|
||||
!to_intel_crtc(tmp_crtc)->primary_disabled &&
|
||||
tmp_crtc->fb) {
|
||||
if (intel_crtc_active(tmp_crtc) &&
|
||||
!to_intel_crtc(tmp_crtc)->primary_disabled) {
|
||||
if (crtc) {
|
||||
DRM_DEBUG_KMS("more than one pipe active, disabling compression\n");
|
||||
dev_priv->no_fbc_reason = FBC_MULTIPLE_PIPES;
|
||||
@@ -995,7 +1002,7 @@ static struct drm_crtc *single_enabled_crtc(struct drm_device *dev)
|
||||
struct drm_crtc *crtc, *enabled = NULL;
|
||||
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
if (to_intel_crtc(crtc)->active && crtc->fb) {
|
||||
if (intel_crtc_active(crtc)) {
|
||||
if (enabled)
|
||||
return NULL;
|
||||
enabled = crtc;
|
||||
@@ -1089,7 +1096,7 @@ static bool g4x_compute_wm0(struct drm_device *dev,
|
||||
int entries, tlb_miss;
|
||||
|
||||
crtc = intel_get_crtc_for_plane(dev, plane);
|
||||
if (crtc->fb == NULL || !to_intel_crtc(crtc)->active) {
|
||||
if (!intel_crtc_active(crtc)) {
|
||||
*cursor_wm = cursor->guard_size;
|
||||
*plane_wm = display->guard_size;
|
||||
return false;
|
||||
@@ -1218,7 +1225,7 @@ static bool vlv_compute_drain_latency(struct drm_device *dev,
|
||||
int entries;
|
||||
|
||||
crtc = intel_get_crtc_for_plane(dev, plane);
|
||||
if (crtc->fb == NULL || !to_intel_crtc(crtc)->active)
|
||||
if (!intel_crtc_active(crtc))
|
||||
return false;
|
||||
|
||||
clock = crtc->mode.clock; /* VESA DOT Clock */
|
||||
@@ -1479,7 +1486,7 @@ static void i9xx_update_wm(struct drm_device *dev)
|
||||
|
||||
fifo_size = dev_priv->display.get_fifo_size(dev, 0);
|
||||
crtc = intel_get_crtc_for_plane(dev, 0);
|
||||
if (to_intel_crtc(crtc)->active && crtc->fb) {
|
||||
if (intel_crtc_active(crtc)) {
|
||||
int cpp = crtc->fb->bits_per_pixel / 8;
|
||||
if (IS_GEN2(dev))
|
||||
cpp = 4;
|
||||
@@ -1493,7 +1500,7 @@ static void i9xx_update_wm(struct drm_device *dev)
|
||||
|
||||
fifo_size = dev_priv->display.get_fifo_size(dev, 1);
|
||||
crtc = intel_get_crtc_for_plane(dev, 1);
|
||||
if (to_intel_crtc(crtc)->active && crtc->fb) {
|
||||
if (intel_crtc_active(crtc)) {
|
||||
int cpp = crtc->fb->bits_per_pixel / 8;
|
||||
if (IS_GEN2(dev))
|
||||
cpp = 4;
|
||||
@@ -2047,7 +2054,7 @@ sandybridge_compute_sprite_wm(struct drm_device *dev, int plane,
|
||||
int entries, tlb_miss;
|
||||
|
||||
crtc = intel_get_crtc_for_plane(dev, plane);
|
||||
if (crtc->fb == NULL || !to_intel_crtc(crtc)->active) {
|
||||
if (!intel_crtc_active(crtc)) {
|
||||
*sprite_wm = display->guard_size;
|
||||
return false;
|
||||
}
|
||||
|
@@ -120,11 +120,10 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
|
||||
I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]);
|
||||
I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
|
||||
|
||||
linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
|
||||
linear_offset = y * fb->pitches[0] + x * pixel_size;
|
||||
sprsurf_offset =
|
||||
intel_gen4_compute_offset_xtiled(&x, &y,
|
||||
fb->bits_per_pixel / 8,
|
||||
fb->pitches[0]);
|
||||
pixel_size, fb->pitches[0]);
|
||||
linear_offset -= sprsurf_offset;
|
||||
|
||||
/* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
|
||||
@@ -286,11 +285,10 @@ ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
|
||||
I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]);
|
||||
I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
|
||||
|
||||
linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
|
||||
linear_offset = y * fb->pitches[0] + x * pixel_size;
|
||||
dvssurf_offset =
|
||||
intel_gen4_compute_offset_xtiled(&x, &y,
|
||||
fb->bits_per_pixel / 8,
|
||||
fb->pitches[0]);
|
||||
pixel_size, fb->pitches[0]);
|
||||
linear_offset -= dvssurf_offset;
|
||||
|
||||
if (obj->tiling_mode != I915_TILING_NONE)
|
||||
@@ -595,7 +593,7 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
|
||||
if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
drm_modeset_lock_all(dev);
|
||||
|
||||
obj = drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE);
|
||||
if (!obj) {
|
||||
@@ -608,7 +606,7 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
|
||||
ret = intel_plane->update_colorkey(plane, set);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
drm_modeset_unlock_all(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -624,7 +622,7 @@ int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
|
||||
if (!drm_core_check_feature(dev, DRIVER_MODESET))
|
||||
return -ENODEV;
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
drm_modeset_lock_all(dev);
|
||||
|
||||
obj = drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE);
|
||||
if (!obj) {
|
||||
@@ -637,7 +635,7 @@ int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
|
||||
intel_plane->get_colorkey(plane, get);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
drm_modeset_unlock_all(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
在新工单中引用
屏蔽一个用户