summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorRob Clark2013-11-19 18:10:12 +0100
committerDave Airlie2014-06-05 01:54:33 +0200
commit51fd371bbaf94018a1223b4e2cf20b9880fd92d4 (patch)
treee86e8ec3ace2fd61111105d39f5eb2d37378e9a8 /drivers/gpu/drm/i915/intel_display.c
parentdrm/dp: add a hw mutex around the transfer functions. (v2) (diff)
downloadkernel-qcow2-linux-51fd371bbaf94018a1223b4e2cf20b9880fd92d4.tar.gz
kernel-qcow2-linux-51fd371bbaf94018a1223b4e2cf20b9880fd92d4.tar.xz
kernel-qcow2-linux-51fd371bbaf94018a1223b4e2cf20b9880fd92d4.zip
drm: convert crtc and connection_mutex to ww_mutex (v5)
For atomic, it will be quite necessary to not need to care so much about locking order. And 'state' gives us a convenient place to stash a ww_ctx for any sort of update that needs to grab multiple crtc locks. Because we will want to eventually make locking even more fine grained (giving locks to planes, connectors, etc), split out drm_modeset_lock and drm_modeset_acquire_ctx to track acquired locks. Atomic will use this to keep track of which locks have been acquired in a transaction. v1: original v2: remove a few things not needed until atomic, for now v3: update for v3 of connection_mutex patch.. v4: squash in docbook v5: doc tweaks/fixes Signed-off-by: Rob Clark <robdclark@gmail.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c56
1 files changed, 37 insertions, 19 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index c2976ade823f..1ce4ad4626e4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2576,7 +2576,7 @@ void intel_display_handle_reset(struct drm_device *dev)
for_each_crtc(dev, crtc) {
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- mutex_lock(&crtc->mutex);
+ drm_modeset_lock(&crtc->mutex, NULL);
/*
* FIXME: Once we have proper support for primary planes (and
* disabling them without disabling the entire crtc) allow again
@@ -2587,7 +2587,7 @@ void intel_display_handle_reset(struct drm_device *dev)
crtc->primary->fb,
crtc->x,
crtc->y);
- mutex_unlock(&crtc->mutex);
+ drm_modeset_unlock(&crtc->mutex);
}
}
@@ -8307,7 +8307,8 @@ mode_fits_in_fbdev(struct drm_device *dev,
bool intel_get_load_detect_pipe(struct drm_connector *connector,
struct drm_display_mode *mode,
- struct intel_load_detect_pipe *old)
+ struct intel_load_detect_pipe *old,
+ struct drm_modeset_acquire_ctx *ctx)
{
struct intel_crtc *intel_crtc;
struct intel_encoder *intel_encoder =
@@ -8317,13 +8318,19 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
struct drm_crtc *crtc = NULL;
struct drm_device *dev = encoder->dev;
struct drm_framebuffer *fb;
- int i = -1;
+ struct drm_mode_config *config = &dev->mode_config;
+ int ret, i = -1;
DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
connector->base.id, connector->name,
encoder->base.id, encoder->name);
- mutex_lock(&dev->mode_config.connection_mutex);
+ drm_modeset_acquire_init(ctx, 0);
+
+retry:
+ ret = drm_modeset_lock(&config->connection_mutex, ctx);
+ if (ret)
+ goto fail_unlock;
/*
* Algorithm gets a little messy:
@@ -8339,7 +8346,9 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
if (encoder->crtc) {
crtc = encoder->crtc;
- mutex_lock(&crtc->mutex);
+ ret = drm_modeset_lock(&crtc->mutex, ctx);
+ if (ret)
+ goto fail_unlock;
old->dpms_mode = connector->dpms;
old->load_detect_temp = false;
@@ -8367,10 +8376,12 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
*/
if (!crtc) {
DRM_DEBUG_KMS("no pipe available for load-detect\n");
- goto fail_unlock_connector;
+ goto fail_unlock;
}
- mutex_lock(&crtc->mutex);
+ ret = drm_modeset_lock(&crtc->mutex, ctx);
+ if (ret)
+ goto fail_unlock;
intel_encoder->new_crtc = to_intel_crtc(crtc);
to_intel_connector(connector)->new_encoder = intel_encoder;
@@ -8420,15 +8431,21 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
intel_crtc->new_config = &intel_crtc->config;
else
intel_crtc->new_config = NULL;
- mutex_unlock(&crtc->mutex);
-fail_unlock_connector:
- mutex_unlock(&dev->mode_config.connection_mutex);
+fail_unlock:
+ if (ret == -EDEADLK) {
+ drm_modeset_backoff(ctx);
+ goto retry;
+ }
+
+ drm_modeset_drop_locks(ctx);
+ drm_modeset_acquire_fini(ctx);
return false;
}
void intel_release_load_detect_pipe(struct drm_connector *connector,
- struct intel_load_detect_pipe *old)
+ struct intel_load_detect_pipe *old,
+ struct drm_modeset_acquire_ctx *ctx)
{
struct intel_encoder *intel_encoder =
intel_attached_encoder(connector);
@@ -8452,8 +8469,7 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
drm_framebuffer_unreference(old->release_fb);
}
- mutex_unlock(&crtc->mutex);
- mutex_unlock(&connector->dev->mode_config.connection_mutex);
+ goto unlock;
return;
}
@@ -8461,8 +8477,9 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
if (old->dpms_mode != DRM_MODE_DPMS_ON)
connector->funcs->dpms(connector, old->dpms_mode);
- mutex_unlock(&crtc->mutex);
- mutex_unlock(&connector->dev->mode_config.connection_mutex);
+unlock:
+ drm_modeset_drop_locks(ctx);
+ drm_modeset_acquire_fini(ctx);
}
static int i9xx_pll_refclk(struct drm_device *dev,
@@ -10995,7 +11012,7 @@ enum pipe intel_get_pipe_from_connector(struct intel_connector *connector)
struct drm_encoder *encoder = connector->base.encoder;
struct drm_device *dev = connector->base.dev;
- WARN_ON(!mutex_is_locked(&dev->mode_config.connection_mutex));
+ WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
if (!encoder)
return INVALID_PIPE;
@@ -11805,6 +11822,7 @@ static void intel_enable_pipe_a(struct drm_device *dev)
struct intel_connector *connector;
struct drm_connector *crt = NULL;
struct intel_load_detect_pipe load_detect_temp;
+ struct drm_modeset_acquire_ctx ctx;
/* We can't just switch on the pipe A, we need to set things up with a
* proper mode and output configuration. As a gross hack, enable pipe A
@@ -11821,8 +11839,8 @@ static void intel_enable_pipe_a(struct drm_device *dev)
if (!crt)
return;
- if (intel_get_load_detect_pipe(crt, NULL, &load_detect_temp))
- intel_release_load_detect_pipe(crt, &load_detect_temp);
+ if (intel_get_load_detect_pipe(crt, NULL, &load_detect_temp, &ctx))
+ intel_release_load_detect_pipe(crt, &load_detect_temp, &ctx);
}