drm/i915: Remove crtc->config dereference from drrs_ctl
Wait for idle, and iterate over connectors instead of encoders. With this information we know crtc->state is the actual state, and we can enable/disable drrs safely. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20181011100457.8776-2-maarten.lankhorst@linux.intel.com Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
This commit is contained in:
@@ -4660,20 +4660,45 @@ static int i915_drrs_ctl_set(void *data, u64 val)
|
|||||||
{
|
{
|
||||||
struct drm_i915_private *dev_priv = data;
|
struct drm_i915_private *dev_priv = data;
|
||||||
struct drm_device *dev = &dev_priv->drm;
|
struct drm_device *dev = &dev_priv->drm;
|
||||||
struct intel_crtc *intel_crtc;
|
struct intel_crtc *crtc;
|
||||||
struct intel_encoder *encoder;
|
|
||||||
struct intel_dp *intel_dp;
|
|
||||||
|
|
||||||
if (INTEL_GEN(dev_priv) < 7)
|
if (INTEL_GEN(dev_priv) < 7)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
drm_modeset_lock_all(dev);
|
for_each_intel_crtc(dev, crtc) {
|
||||||
for_each_intel_crtc(dev, intel_crtc) {
|
struct drm_connector_list_iter conn_iter;
|
||||||
if (!intel_crtc->base.state->active ||
|
struct intel_crtc_state *crtc_state;
|
||||||
!intel_crtc->config->has_drrs)
|
struct drm_connector *connector;
|
||||||
continue;
|
struct drm_crtc_commit *commit;
|
||||||
|
int ret;
|
||||||
|
|
||||||
for_each_encoder_on_crtc(dev, &intel_crtc->base, encoder) {
|
ret = drm_modeset_lock_single_interruptible(&crtc->base.mutex);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
crtc_state = to_intel_crtc_state(crtc->base.state);
|
||||||
|
|
||||||
|
if (!crtc_state->base.active ||
|
||||||
|
!crtc_state->has_drrs)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
commit = crtc_state->base.commit;
|
||||||
|
if (commit) {
|
||||||
|
ret = wait_for_completion_interruptible(&commit->hw_done);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
drm_connector_list_iter_begin(dev, &conn_iter);
|
||||||
|
drm_for_each_connector_iter(connector, &conn_iter) {
|
||||||
|
struct intel_encoder *encoder;
|
||||||
|
struct intel_dp *intel_dp;
|
||||||
|
|
||||||
|
if (!(crtc_state->base.connector_mask &
|
||||||
|
drm_connector_mask(connector)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
encoder = intel_attached_encoder(connector);
|
||||||
if (encoder->type != INTEL_OUTPUT_EDP)
|
if (encoder->type != INTEL_OUTPUT_EDP)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -4683,13 +4708,18 @@ static int i915_drrs_ctl_set(void *data, u64 val)
|
|||||||
intel_dp = enc_to_intel_dp(&encoder->base);
|
intel_dp = enc_to_intel_dp(&encoder->base);
|
||||||
if (val)
|
if (val)
|
||||||
intel_edp_drrs_enable(intel_dp,
|
intel_edp_drrs_enable(intel_dp,
|
||||||
intel_crtc->config);
|
crtc_state);
|
||||||
else
|
else
|
||||||
intel_edp_drrs_disable(intel_dp,
|
intel_edp_drrs_disable(intel_dp,
|
||||||
intel_crtc->config);
|
crtc_state);
|
||||||
}
|
}
|
||||||
|
drm_connector_list_iter_end(&conn_iter);
|
||||||
|
|
||||||
|
out:
|
||||||
|
drm_modeset_unlock(&crtc->base.mutex);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
drm_modeset_unlock_all(dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user