diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2009-09-15 16:57:34 -0400 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2009-11-05 17:47:08 -0500 |
commit | 02e792fbaadb75dec8e476a05b610e49908fc6a4 (patch) | |
tree | 3c813fbf64431827b0e56291c647e60443a52277 /drivers/gpu/drm/i915/intel_display.c | |
parent | f0f8a9cecea322b215600d96cf0c1eb08343a4e9 (diff) |
drm/i915: implement drmmode overlay support v4
This implements intel overlay support for kms via a device-specific
ioctl. Thomas Hellstrom brought up the idea of a general ioctl (on
dri-devel). We've reached the conclusion that such an infrastructure
only makes sense when multiple kms overlay implementations exists,
which atm don't (and it doesn't look like this is gonna change).
Open issues:
- Runs in sync with the gpu, i.e. unnecessary waiting. I've decided
to wait on this because the hw tends to hang when changing something
in this area. I left some dummy functions as infrastructure.
- polyphase filtering uses a static table.
- uses uninterruptible sleeps. Unfortunately the alternatives may
unnecessarily wedged the hw if/when we timeout too early (and
userspace only overloaded the batch buffers with stuff worth a few
secs of gpu time).
Changes since v1:
- fix off-by-one misconception on my side. This fixes fullscreen
playback.
Changes since v2:
- add underrun detection as spec'ed for i965.
- flush caches properly, fixing visual corruptions.
Changes since v4:
- fix up cache flushing of overlay memory regs.
- killed require_pipe_a logic - it hangs the chip.
Tested-By: diego.abelenda@gmail.com (on a 865G)
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
[anholt: Resolved against the MADVISE ioctl going in before this one]
Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0be624a52e50..6f818fadcbe3 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1781,6 +1781,22 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1781 | } | 1781 | } |
1782 | } | 1782 | } |
1783 | 1783 | ||
1784 | static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable) | ||
1785 | { | ||
1786 | struct intel_overlay *overlay; | ||
1787 | |||
1788 | if (!enable && intel_crtc->overlay) { | ||
1789 | overlay = intel_crtc->overlay; | ||
1790 | mutex_lock(&overlay->dev->struct_mutex); | ||
1791 | intel_overlay_switch_off(overlay); | ||
1792 | mutex_unlock(&overlay->dev->struct_mutex); | ||
1793 | } | ||
1794 | /* Let userspace switch the overlay on again. In most cases userspace | ||
1795 | * has to recompute where to put it anyway. */ | ||
1796 | |||
1797 | return; | ||
1798 | } | ||
1799 | |||
1784 | static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | 1800 | static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) |
1785 | { | 1801 | { |
1786 | struct drm_device *dev = crtc->dev; | 1802 | struct drm_device *dev = crtc->dev; |
@@ -1839,12 +1855,13 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1839 | intel_update_fbc(crtc, &crtc->mode); | 1855 | intel_update_fbc(crtc, &crtc->mode); |
1840 | 1856 | ||
1841 | /* Give the overlay scaler a chance to enable if it's on this pipe */ | 1857 | /* Give the overlay scaler a chance to enable if it's on this pipe */ |
1842 | //intel_crtc_dpms_video(crtc, true); TODO | 1858 | intel_crtc_dpms_overlay(intel_crtc, true); |
1843 | break; | 1859 | break; |
1844 | case DRM_MODE_DPMS_OFF: | 1860 | case DRM_MODE_DPMS_OFF: |
1845 | intel_update_watermarks(dev); | 1861 | intel_update_watermarks(dev); |
1862 | |||
1846 | /* Give the overlay scaler a chance to disable if it's on this pipe */ | 1863 | /* Give the overlay scaler a chance to disable if it's on this pipe */ |
1847 | //intel_crtc_dpms_video(crtc, FALSE); TODO | 1864 | intel_crtc_dpms_overlay(intel_crtc, false); |
1848 | 1865 | ||
1849 | if (dev_priv->cfb_plane == plane && | 1866 | if (dev_priv->cfb_plane == plane && |
1850 | dev_priv->display.disable_fbc) | 1867 | dev_priv->display.disable_fbc) |
@@ -2039,7 +2056,7 @@ static int i830_get_display_clock_speed(struct drm_device *dev) | |||
2039 | * Return the pipe currently connected to the panel fitter, | 2056 | * Return the pipe currently connected to the panel fitter, |
2040 | * or -1 if the panel fitter is not present or not in use | 2057 | * or -1 if the panel fitter is not present or not in use |
2041 | */ | 2058 | */ |
2042 | static int intel_panel_fitter_pipe (struct drm_device *dev) | 2059 | int intel_panel_fitter_pipe (struct drm_device *dev) |
2043 | { | 2060 | { |
2044 | struct drm_i915_private *dev_priv = dev->dev_private; | 2061 | struct drm_i915_private *dev_priv = dev->dev_private; |
2045 | u32 pfit_control; | 2062 | u32 pfit_control; |
@@ -4458,6 +4475,8 @@ void intel_modeset_init(struct drm_device *dev) | |||
4458 | INIT_WORK(&dev_priv->idle_work, intel_idle_update); | 4475 | INIT_WORK(&dev_priv->idle_work, intel_idle_update); |
4459 | setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, | 4476 | setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, |
4460 | (unsigned long)dev); | 4477 | (unsigned long)dev); |
4478 | |||
4479 | intel_setup_overlay(dev); | ||
4461 | } | 4480 | } |
4462 | 4481 | ||
4463 | void intel_modeset_cleanup(struct drm_device *dev) | 4482 | void intel_modeset_cleanup(struct drm_device *dev) |