drm/i915: skip redundant operations whilst enabling pipes and planes

If the pipe or plane is already enabled, then we do not need to enable
it again and can skip the delay. Similarly if it is already disabled
when we want to disable it, we can also skip it.

This fixes a regression from b24e717988, which caused the LVDS
output on one PineView machine to become corrupt after changing
orientation several times.

References: https://bugs.freedesktop.org/show_bug.cgi?id=34601
Cc: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Keith Packard <keithp@keithp.com>
Tested-by: mengmeng.meng@intel.com

+16 -8
+16 -8
drivers/gpu/drm/i915/intel_display.c
··· 1516 1517 reg = PIPECONF(pipe); 1518 val = I915_READ(reg); 1519 - val |= PIPECONF_ENABLE; 1520 - I915_WRITE(reg, val); 1521 intel_wait_for_vblank(dev_priv->dev, pipe); 1522 } 1523 ··· 1553 1554 reg = PIPECONF(pipe); 1555 val = I915_READ(reg); 1556 - val &= ~PIPECONF_ENABLE; 1557 - I915_WRITE(reg, val); 1558 intel_wait_for_pipe_off(dev_priv->dev, pipe); 1559 } 1560 ··· 1579 1580 reg = DSPCNTR(plane); 1581 val = I915_READ(reg); 1582 - val |= DISPLAY_PLANE_ENABLE; 1583 - I915_WRITE(reg, val); 1584 intel_wait_for_vblank(dev_priv->dev, pipe); 1585 } 1586 ··· 1613 1614 reg = DSPCNTR(plane); 1615 val = I915_READ(reg); 1616 - val &= ~DISPLAY_PLANE_ENABLE; 1617 - I915_WRITE(reg, val); 1618 intel_flush_display_plane(dev_priv, plane); 1619 intel_wait_for_vblank(dev_priv->dev, pipe); 1620 }
··· 1516 1517 reg = PIPECONF(pipe); 1518 val = I915_READ(reg); 1519 + if (val & PIPECONF_ENABLE) 1520 + return; 1521 + 1522 + I915_WRITE(reg, val | PIPECONF_ENABLE); 1523 intel_wait_for_vblank(dev_priv->dev, pipe); 1524 } 1525 ··· 1551 1552 reg = PIPECONF(pipe); 1553 val = I915_READ(reg); 1554 + if ((val & PIPECONF_ENABLE) == 0) 1555 + return; 1556 + 1557 + I915_WRITE(reg, val & ~PIPECONF_ENABLE); 1558 intel_wait_for_pipe_off(dev_priv->dev, pipe); 1559 } 1560 ··· 1575 1576 reg = DSPCNTR(plane); 1577 val = I915_READ(reg); 1578 + if (val & DISPLAY_PLANE_ENABLE) 1579 + return; 1580 + 1581 + I915_WRITE(reg, val | DISPLAY_PLANE_ENABLE); 1582 intel_wait_for_vblank(dev_priv->dev, pipe); 1583 } 1584 ··· 1607 1608 reg = DSPCNTR(plane); 1609 val = I915_READ(reg); 1610 + if ((val & DISPLAY_PLANE_ENABLE) == 0) 1611 + return; 1612 + 1613 + I915_WRITE(reg, val & ~DISPLAY_PLANE_ENABLE); 1614 intel_flush_display_plane(dev_priv, plane); 1615 intel_wait_for_vblank(dev_priv->dev, pipe); 1616 }