From 01dcc47d895997f77c9457558e974d41c23ed4e1 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 28 Feb 2008 16:24:17 +1000 Subject: drm: add modesetting as a driver feature. This change adds a driver feature that for i915 is controlled by a module parameter. You now need to do insmod i915.ko modeset=1 to enable it the modesetting paths. It also fixes up lots of X paths. I can run my new DDX driver on this code with and without modesetting enabled --- shared-core/i915_dma.c | 49 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 5 deletions(-) (limited to 'shared-core/i915_dma.c') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index eee24dd1..20095a95 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -66,6 +66,11 @@ void i915_kernel_lost_context(struct drm_device * dev) struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_ring_buffer *ring = &(dev_priv->ring); + /* we should never lose context on the ring with modesetting + * as we don't expose it to userspace */ + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return; + ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; ring->tail = I915_READ(LP_RING + RING_TAIL) & TAIL_ADDR; ring->space = ring->head - (ring->tail + 8); @@ -75,6 +80,11 @@ void i915_kernel_lost_context(struct drm_device * dev) int i915_dma_cleanup(struct drm_device * dev) { + struct drm_i915_private *dev_priv = dev->dev_private; + + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + /* Make sure interrupts are disabled here because the uninstall ioctl * may not have been called from userspace and after dev_private * is freed, it's too late. @@ -82,6 +92,28 @@ int i915_dma_cleanup(struct drm_device * dev) if (dev->irq) drm_irq_uninstall(dev); + if (dev_priv->ring.virtual_start) { + drm_core_ioremapfree(&dev_priv->ring.map, dev); + dev_priv->ring.virtual_start = 0; + dev_priv->ring.map.handle = 0; + dev_priv->ring.map.size = 0; + dev_priv->ring.Size = 0; + } + + if (dev_priv->status_page_dmah) { + drm_pci_free(dev, dev_priv->status_page_dmah); + dev_priv->status_page_dmah = NULL; + /* Need to rewrite hardware status page */ + I915_WRITE(0x02080, 0x1ffff000); + } + + if (dev_priv->status_gfx_addr) { + dev_priv->status_gfx_addr = 0; + drm_core_ioremapfree(&dev_priv->hws_map, dev); + I915_WRITE(0x02080, 0x1ffff000); + } + + return 0; } @@ -153,13 +185,17 @@ static int i915_initialize(struct drm_device * dev, struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; - dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset); - if (!dev_priv->mmio_map) { - i915_dma_cleanup(dev); - DRM_ERROR("can not find mmio map!\n"); - return -EINVAL; + if (!drm_core_check_feature(dev, DRIVER_MODESET)) { + if (init->mmio_offset != 0) + dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset); + if (!dev_priv->mmio_map) { + i915_dma_cleanup(dev); + DRM_ERROR("can not find mmio map!\n"); + return -EINVAL; + } } + #ifdef I915_HAVE_BUFFER dev_priv->max_validate_buffers = I915_MAX_VALIDATE_BUFFERS; #endif @@ -246,6 +282,9 @@ static int i915_dma_resume(struct drm_device * dev) DRM_DEBUG("\n"); + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + if (!dev_priv->mmio_map) { DRM_ERROR("can not find mmio map!\n"); return -EINVAL; -- cgit v1.2.3