Skip to content

Commit

Permalink
drm/i915/tv: Use polling rather than interrupt-based hotplug
Browse files Browse the repository at this point in the history
The documentation recommends that we should use a polling method for TV
detection as this is more power efficient than the interrupt based
mechanism (as the encoder can be completely switched off). A secondary
effect is that leaving the hotplug enabled seems to be causing pipe
underruns as reported by Hugh Dickins on his Crestline.

Tested-by: Hugh Dickins <hughd@google.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
[This is a candidate for stable, but needs minor porting to 2.6.37]
  • Loading branch information
Chris Wilson committed Feb 11, 2011
1 parent 1aad7ac commit 8102e12
Showing 1 changed file with 30 additions and 13 deletions.
43 changes: 30 additions & 13 deletions drivers/gpu/drm/i915/intel_tv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1234,7 +1234,8 @@ static const struct drm_display_mode reported_modes[] = {
* \return false if TV is disconnected.
*/
static int
intel_tv_detect_type (struct intel_tv *intel_tv)
intel_tv_detect_type (struct intel_tv *intel_tv,
struct drm_connector *connector)
{
struct drm_encoder *encoder = &intel_tv->base.base;
struct drm_device *dev = encoder->dev;
Expand All @@ -1245,11 +1246,13 @@ intel_tv_detect_type (struct intel_tv *intel_tv)
int type;

/* Disable TV interrupts around load detect or we'll recurse */
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
i915_disable_pipestat(dev_priv, 0,
PIPE_HOTPLUG_INTERRUPT_ENABLE |
PIPE_HOTPLUG_TV_INTERRUPT_ENABLE);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
i915_disable_pipestat(dev_priv, 0,
PIPE_HOTPLUG_INTERRUPT_ENABLE |
PIPE_HOTPLUG_TV_INTERRUPT_ENABLE);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
}

save_tv_dac = tv_dac = I915_READ(TV_DAC);
save_tv_ctl = tv_ctl = I915_READ(TV_CTL);
Expand Down Expand Up @@ -1302,11 +1305,13 @@ intel_tv_detect_type (struct intel_tv *intel_tv)
I915_WRITE(TV_CTL, save_tv_ctl);

/* Restore interrupt config */
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
i915_enable_pipestat(dev_priv, 0,
PIPE_HOTPLUG_INTERRUPT_ENABLE |
PIPE_HOTPLUG_TV_INTERRUPT_ENABLE);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
i915_enable_pipestat(dev_priv, 0,
PIPE_HOTPLUG_INTERRUPT_ENABLE |
PIPE_HOTPLUG_TV_INTERRUPT_ENABLE);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
}

return type;
}
Expand Down Expand Up @@ -1356,15 +1361,15 @@ intel_tv_detect(struct drm_connector *connector, bool force)
drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V);

if (intel_tv->base.base.crtc && intel_tv->base.base.crtc->enabled) {
type = intel_tv_detect_type(intel_tv);
type = intel_tv_detect_type(intel_tv, connector);
} else if (force) {
struct drm_crtc *crtc;
int dpms_mode;

crtc = intel_get_load_detect_pipe(&intel_tv->base, connector,
&mode, &dpms_mode);
if (crtc) {
type = intel_tv_detect_type(intel_tv);
type = intel_tv_detect_type(intel_tv, connector);
intel_release_load_detect_pipe(&intel_tv->base, connector,
dpms_mode);
} else
Expand Down Expand Up @@ -1658,6 +1663,18 @@ intel_tv_init(struct drm_device *dev)
intel_encoder = &intel_tv->base;
connector = &intel_connector->base;

/* The documentation, for the older chipsets at least, recommend
* using a polling method rather than hotplug detection for TVs.
* This is because in order to perform the hotplug detection, the PLLs
* for the TV must be kept alive increasing power drain and starving
* bandwidth from other encoders. Notably for instance, it causes
* pipe underruns on Crestline when this encoder is supposedly idle.
*
* More recent chipsets favour HDMI rather than integrated S-Video.
*/
connector->polled =
DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;

drm_connector_init(dev, connector, &intel_tv_connector_funcs,
DRM_MODE_CONNECTOR_SVIDEO);

Expand Down

0 comments on commit 8102e12

Please sign in to comment.