diff options
author | Sean Paul <seanpaul@chromium.org> | 2018-11-16 13:42:22 -0500 |
---|---|---|
committer | Rob Clark <robdclark@gmail.com> | 2018-12-11 13:10:11 -0500 |
commit | 18a63b3c6f0b6247f93f5eb05353b0486512017e (patch) | |
tree | f1c41e65a3f895437f671f29bb8d5261d8cdc997 /drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | |
parent | fba7427eb594964726ab92bde7b9c20c995b4685 (diff) | |
download | linux-18a63b3c6f0b6247f93f5eb05353b0486512017e.tar.gz linux-18a63b3c6f0b6247f93f5eb05353b0486512017e.tar.bz2 linux-18a63b3c6f0b6247f93f5eb05353b0486512017e.zip |
drm/msm: dpu: Move crtc runtime resume to encoder
The crtc runtime resume doesn't actually operate on the crtc, but rather
its encoders. The problem with this is that we need to inspect the crtc
state to get the currently connected encoders. Since runtime resume
isn't guaranteed to be called while holding the modeset locks (although
it sometimes is), this presents a race condition.
Now that we have ->enabled on the virtual encoders, and a lock to
protect it, just call resume on each encoder and only restore the ones
that are enabled.
Changes in v2:
- None
Cc: Jeykumar Sankaran <jsanka@codeaurora.org>
Reviewed-by: Jeykumar Sankaran <jsanka@codeaurora.org>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c')
-rw-r--r-- | drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 24 |
1 files changed, 10 insertions, 14 deletions
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index c1b32ef1fc46..83b25a1f65d6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1089,28 +1089,24 @@ static void _dpu_encoder_virt_enable_helper(struct drm_encoder *drm_enc) _dpu_encoder_update_vsync_source(dpu_enc, &dpu_enc->disp_info); } -void dpu_encoder_virt_restore(struct drm_encoder *drm_enc) +void dpu_encoder_virt_runtime_resume(struct drm_encoder *drm_enc) { - struct dpu_encoder_virt *dpu_enc = NULL; - int i; - - if (!drm_enc) { - DPU_ERROR("invalid encoder\n"); - return; - } - dpu_enc = to_dpu_encoder_virt(drm_enc); + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc); - for (i = 0; i < dpu_enc->num_phys_encs; i++) { - struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; + mutex_lock(&dpu_enc->enc_lock); - if (phys && (phys != dpu_enc->cur_master) && phys->ops.restore) - phys->ops.restore(phys); - } + if (!dpu_enc->enabled) + goto out; + if (dpu_enc->cur_slave && dpu_enc->cur_slave->ops.restore) + dpu_enc->cur_slave->ops.restore(dpu_enc->cur_slave); if (dpu_enc->cur_master && dpu_enc->cur_master->ops.restore) dpu_enc->cur_master->ops.restore(dpu_enc->cur_master); _dpu_encoder_virt_enable_helper(drm_enc); + +out: + mutex_unlock(&dpu_enc->enc_lock); } static void dpu_encoder_virt_enable(struct drm_encoder *drm_enc) |