mirror of https://gitee.com/openkylin/linux.git
drm/i915: Ensure the HW is powered when accessing the CRC HW block
The assumption when adding the intel_display_power_is_enabled() checks was that if it returns success the power can't be turned off afterwards during the HW access, which is guaranteed by modeset locks. This isn't always true, so make sure we hold a dedicated reference for the time of the access. While at it also add the missing reference around the HW access in i915_interrupt_info(). v2: - update the commit message mentioning that this also fixes the HW access in the interrupt info debugfs entry (Daniel) Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1455296121-4742-9-git-send-email-imre.deak@intel.com
This commit is contained in:
parent
e27daab497
commit
e129649b7a
|
@ -825,8 +825,11 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
|
|||
}
|
||||
|
||||
for_each_pipe(dev_priv, pipe) {
|
||||
if (!intel_display_power_is_enabled(dev_priv,
|
||||
POWER_DOMAIN_PIPE(pipe))) {
|
||||
enum intel_display_power_domain power_domain;
|
||||
|
||||
power_domain = POWER_DOMAIN_PIPE(pipe);
|
||||
if (!intel_display_power_get_if_enabled(dev_priv,
|
||||
power_domain)) {
|
||||
seq_printf(m, "Pipe %c power disabled\n",
|
||||
pipe_name(pipe));
|
||||
continue;
|
||||
|
@ -840,6 +843,8 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
|
|||
seq_printf(m, "Pipe %c IER:\t%08x\n",
|
||||
pipe_name(pipe),
|
||||
I915_READ(GEN8_DE_PIPE_IER(pipe)));
|
||||
|
||||
intel_display_power_put(dev_priv, power_domain);
|
||||
}
|
||||
|
||||
seq_printf(m, "Display Engine port interrupt mask:\t%08x\n",
|
||||
|
@ -4004,6 +4009,7 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
|
|||
struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe];
|
||||
struct intel_crtc *crtc = to_intel_crtc(intel_get_crtc_for_pipe(dev,
|
||||
pipe));
|
||||
enum intel_display_power_domain power_domain;
|
||||
u32 val = 0; /* shut up gcc */
|
||||
int ret;
|
||||
|
||||
|
@ -4014,7 +4020,8 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
|
|||
if (pipe_crc->source && source)
|
||||
return -EINVAL;
|
||||
|
||||
if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(pipe))) {
|
||||
power_domain = POWER_DOMAIN_PIPE(pipe);
|
||||
if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) {
|
||||
DRM_DEBUG_KMS("Trying to capture CRC while pipe is off\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -4031,7 +4038,7 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
|
|||
ret = ivb_pipe_crc_ctl_reg(dev, pipe, &source, &val);
|
||||
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
goto out;
|
||||
|
||||
/* none -> real source transition */
|
||||
if (source) {
|
||||
|
@ -4043,8 +4050,10 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
|
|||
entries = kcalloc(INTEL_PIPE_CRC_ENTRIES_NR,
|
||||
sizeof(pipe_crc->entries[0]),
|
||||
GFP_KERNEL);
|
||||
if (!entries)
|
||||
return -ENOMEM;
|
||||
if (!entries) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* When IPS gets enabled, the pipe CRC changes. Since IPS gets
|
||||
|
@ -4100,7 +4109,12 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
|
|||
hsw_enable_ips(crtc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
intel_display_power_put(dev_priv, power_domain);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue