drm/i915: Switch to using pci_iounmap in conjunction with pci_iomap
[pandora-kernel.git] / drivers / gpu / drm / i915 / i915_dma.c
index 1851ca4..eee88cf 100644 (file)
@@ -131,9 +131,9 @@ static int i915_dma_cleanup(struct drm_device * dev)
                drm_irq_uninstall(dev);
 
        mutex_lock(&dev->struct_mutex);
-       intel_cleanup_ring_buffer(dev, &dev_priv->render_ring);
-       intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring);
-       intel_cleanup_ring_buffer(dev, &dev_priv->blt_ring);
+       intel_cleanup_ring_buffer(&dev_priv->render_ring);
+       intel_cleanup_ring_buffer(&dev_priv->bsd_ring);
+       intel_cleanup_ring_buffer(&dev_priv->blt_ring);
        mutex_unlock(&dev->struct_mutex);
 
        /* Clear the HWS virtual address at teardown */
@@ -221,7 +221,7 @@ static int i915_dma_resume(struct drm_device * dev)
        DRM_DEBUG_DRIVER("hw status page @ %p\n",
                                ring->status_page.page_addr);
        if (ring->status_page.gfx_addr != 0)
-               intel_ring_setup_status_page(dev, ring);
+               intel_ring_setup_status_page(ring);
        else
                I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
 
@@ -263,7 +263,7 @@ static int i915_dma_init(struct drm_device *dev, void *data,
  * instruction detected will be given a size of zero, which is a
  * signal to abort the rest of the buffer.
  */
-static int do_validate_cmd(int cmd)
+static int validate_cmd(int cmd)
 {
        switch (((cmd >> 29) & 0x7)) {
        case 0x0:
@@ -321,40 +321,27 @@ static int do_validate_cmd(int cmd)
        return 0;
 }
 
-static int validate_cmd(int cmd)
-{
-       int ret = do_validate_cmd(cmd);
-
-/*     printk("validate_cmd( %x ): %d\n", cmd, ret); */
-
-       return ret;
-}
-
 static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
-       int i;
+       int i, ret;
 
        if ((dwords+1) * sizeof(int) >= dev_priv->render_ring.size - 8)
                return -EINVAL;
 
-       BEGIN_LP_RING((dwords+1)&~1);
-
        for (i = 0; i < dwords;) {
-               int cmd, sz;
-
-               cmd = buffer[i];
-
-               if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords)
+               int sz = validate_cmd(buffer[i]);
+               if (sz == 0 || i + sz > dwords)
                        return -EINVAL;
-
-               OUT_RING(cmd);
-
-               while (++i, --sz) {
-                       OUT_RING(buffer[i]);
-               }
+               i += sz;
        }
 
+       ret = BEGIN_LP_RING((dwords+1)&~1);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < dwords; i++)
+               OUT_RING(buffer[i]);
        if (dwords & 1)
                OUT_RING(0);
 
@@ -368,7 +355,9 @@ i915_emit_box(struct drm_device *dev,
              struct drm_clip_rect *boxes,
              int i, int DR1, int DR4)
 {
+       struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_clip_rect box = boxes[i];
+       int ret;
 
        if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) {
                DRM_ERROR("Bad box %d,%d..%d,%d\n",
@@ -377,22 +366,27 @@ i915_emit_box(struct drm_device *dev,
        }
 
        if (INTEL_INFO(dev)->gen >= 4) {
-               BEGIN_LP_RING(4);
+               ret = BEGIN_LP_RING(4);
+               if (ret)
+                       return ret;
+
                OUT_RING(GFX_OP_DRAWRECT_INFO_I965);
                OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
                OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
                OUT_RING(DR4);
-               ADVANCE_LP_RING();
        } else {
-               BEGIN_LP_RING(6);
+               ret = BEGIN_LP_RING(6);
+               if (ret)
+                       return ret;
+
                OUT_RING(GFX_OP_DRAWRECT_INFO);
                OUT_RING(DR1);
                OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
                OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
                OUT_RING(DR4);
                OUT_RING(0);
-               ADVANCE_LP_RING();
        }
+       ADVANCE_LP_RING();
 
        return 0;
 }
@@ -412,12 +406,13 @@ static void i915_emit_breadcrumb(struct drm_device *dev)
        if (master_priv->sarea_priv)
                master_priv->sarea_priv->last_enqueue = dev_priv->counter;
 
-       BEGIN_LP_RING(4);
-       OUT_RING(MI_STORE_DWORD_INDEX);
-       OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
-       OUT_RING(dev_priv->counter);
-       OUT_RING(0);
-       ADVANCE_LP_RING();
+       if (BEGIN_LP_RING(4) == 0) {
+               OUT_RING(MI_STORE_DWORD_INDEX);
+               OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
+               OUT_RING(dev_priv->counter);
+               OUT_RING(0);
+               ADVANCE_LP_RING();
+       }
 }
 
 static int i915_dispatch_cmdbuffer(struct drm_device * dev,
@@ -458,8 +453,9 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,
                                     drm_i915_batchbuffer_t * batch,
                                     struct drm_clip_rect *cliprects)
 {
+       struct drm_i915_private *dev_priv = dev->dev_private;
        int nbox = batch->num_cliprects;
-       int i = 0, count;
+       int i, count, ret;
 
        if ((batch->start | batch->used) & 0x7) {
                DRM_ERROR("alignment");
@@ -469,17 +465,19 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,
        i915_kernel_lost_context(dev);
 
        count = nbox ? nbox : 1;
-
        for (i = 0; i < count; i++) {
                if (i < nbox) {
-                       int ret = i915_emit_box(dev, cliprects, i,
-                                               batch->DR1, batch->DR4);
+                       ret = i915_emit_box(dev, cliprects, i,
+                                           batch->DR1, batch->DR4);
                        if (ret)
                                return ret;
                }
 
                if (!IS_I830(dev) && !IS_845G(dev)) {
-                       BEGIN_LP_RING(2);
+                       ret = BEGIN_LP_RING(2);
+                       if (ret)
+                               return ret;
+
                        if (INTEL_INFO(dev)->gen >= 4) {
                                OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965);
                                OUT_RING(batch->start);
@@ -487,26 +485,29 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,
                                OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));
                                OUT_RING(batch->start | MI_BATCH_NON_SECURE);
                        }
-                       ADVANCE_LP_RING();
                } else {
-                       BEGIN_LP_RING(4);
+                       ret = BEGIN_LP_RING(4);
+                       if (ret)
+                               return ret;
+
                        OUT_RING(MI_BATCH_BUFFER);
                        OUT_RING(batch->start | MI_BATCH_NON_SECURE);
                        OUT_RING(batch->start + batch->used - 4);
                        OUT_RING(0);
-                       ADVANCE_LP_RING();
                }
+               ADVANCE_LP_RING();
        }
 
 
-       if (IS_G4X(dev) || IS_IRONLAKE(dev)) {
-               BEGIN_LP_RING(2);
-               OUT_RING(MI_FLUSH | MI_NO_WRITE_FLUSH | MI_INVALIDATE_ISP);
-               OUT_RING(MI_NOOP);
-               ADVANCE_LP_RING();
+       if (IS_G4X(dev) || IS_GEN5(dev)) {
+               if (BEGIN_LP_RING(2) == 0) {
+                       OUT_RING(MI_FLUSH | MI_NO_WRITE_FLUSH | MI_INVALIDATE_ISP);
+                       OUT_RING(MI_NOOP);
+                       ADVANCE_LP_RING();
+               }
        }
-       i915_emit_breadcrumb(dev);
 
+       i915_emit_breadcrumb(dev);
        return 0;
 }
 
@@ -515,6 +516,7 @@ static int i915_dispatch_flip(struct drm_device * dev)
        drm_i915_private_t *dev_priv = dev->dev_private;
        struct drm_i915_master_private *master_priv =
                dev->primary->master->driver_priv;
+       int ret;
 
        if (!master_priv->sarea_priv)
                return -EINVAL;
@@ -526,12 +528,13 @@ static int i915_dispatch_flip(struct drm_device * dev)
 
        i915_kernel_lost_context(dev);
 
-       BEGIN_LP_RING(2);
+       ret = BEGIN_LP_RING(10);
+       if (ret)
+               return ret;
+
        OUT_RING(MI_FLUSH | MI_READ_FLUSH);
        OUT_RING(0);
-       ADVANCE_LP_RING();
 
-       BEGIN_LP_RING(6);
        OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP);
        OUT_RING(0);
        if (dev_priv->current_page == 0) {
@@ -542,21 +545,21 @@ static int i915_dispatch_flip(struct drm_device * dev)
                dev_priv->current_page = 0;
        }
        OUT_RING(0);
-       ADVANCE_LP_RING();
 
-       BEGIN_LP_RING(2);
        OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP);
        OUT_RING(0);
+
        ADVANCE_LP_RING();
 
        master_priv->sarea_priv->last_enqueue = dev_priv->counter++;
 
-       BEGIN_LP_RING(4);
-       OUT_RING(MI_STORE_DWORD_INDEX);
-       OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
-       OUT_RING(dev_priv->counter);
-       OUT_RING(0);
-       ADVANCE_LP_RING();
+       if (BEGIN_LP_RING(4) == 0) {
+               OUT_RING(MI_STORE_DWORD_INDEX);
+               OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
+               OUT_RING(dev_priv->counter);
+               OUT_RING(0);
+               ADVANCE_LP_RING();
+       }
 
        master_priv->sarea_priv->pf_current_page = dev_priv->current_page;
        return 0;
@@ -567,7 +570,7 @@ static int i915_quiescent(struct drm_device * dev)
        drm_i915_private_t *dev_priv = dev->dev_private;
 
        i915_kernel_lost_context(dev);
-       return intel_wait_ring_buffer(dev, &dev_priv->render_ring,
+       return intel_wait_ring_buffer(&dev_priv->render_ring,
                                      dev_priv->render_ring.size - 8);
 }
 
@@ -767,6 +770,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
        case I915_PARAM_HAS_BLT:
                value = HAS_BLT(dev);
                break;
+       case I915_PARAM_HAS_RELAXED_FENCING:
+               value = 1;
+               break;
        default:
                DRM_DEBUG_DRIVER("Unknown parameter %d\n",
                                 param->param);
@@ -1192,13 +1198,17 @@ static bool i915_switcheroo_can_switch(struct pci_dev *pdev)
        return can_switch;
 }
 
-static int i915_load_modeset_init(struct drm_device *dev,
-                                 unsigned long prealloc_size,
-                                 unsigned long agp_size)
+static int i915_load_modeset_init(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
+       unsigned long prealloc_size, gtt_size, mappable_size;
        int ret = 0;
 
+       prealloc_size = dev_priv->mm.gtt->gtt_stolen_entries << PAGE_SHIFT;
+       gtt_size = dev_priv->mm.gtt->gtt_total_entries << PAGE_SHIFT;
+       mappable_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT;
+       gtt_size -= PAGE_SIZE;
+
        /* Basic memrange allocator for stolen space (aka mm.vram) */
        drm_mm_init(&dev_priv->mm.vram, 0, prealloc_size);
 
@@ -1211,7 +1221,7 @@ static int i915_load_modeset_init(struct drm_device *dev,
         * at the last page of the aperture.  One page should be enough to
         * keep any prefetching inside of the aperture.
         */
-       i915_gem_do_init(dev, prealloc_size, agp_size - 4096);
+       i915_gem_do_init(dev, prealloc_size, mappable_size, gtt_size);
 
        mutex_lock(&dev->struct_mutex);
        ret = i915_gem_init_ringbuffer(dev);
@@ -1881,7 +1891,6 @@ EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable);
 int i915_driver_load(struct drm_device *dev, unsigned long flags)
 {
        struct drm_i915_private *dev_priv;
-       resource_size_t base, size;
        int ret = 0, mmio_bar;
        uint32_t agp_size, prealloc_size;
        /* i915 has 4 more counters */
@@ -1899,11 +1908,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
        dev_priv->dev = dev;
        dev_priv->info = (struct intel_device_info *) flags;
 
-       /* Add register map (needed for suspend/resume) */
-       mmio_bar = IS_GEN2(dev) ? 1 : 0;
-       base = pci_resource_start(dev->pdev, mmio_bar);
-       size = pci_resource_len(dev->pdev, mmio_bar);
-
        if (i915_get_bridge_dev(dev)) {
                ret = -EIO;
                goto free_priv;
@@ -1913,16 +1917,26 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
        if (IS_GEN2(dev))
                dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30));
 
-       dev_priv->regs = ioremap(base, size);
+       mmio_bar = IS_GEN2(dev) ? 1 : 0;
+       dev_priv->regs = pci_iomap(dev->pdev, mmio_bar, 0);
        if (!dev_priv->regs) {
                DRM_ERROR("failed to map registers\n");
                ret = -EIO;
                goto put_bridge;
        }
 
+       dev_priv->mm.gtt = intel_gtt_get();
+       if (!dev_priv->mm.gtt) {
+               DRM_ERROR("Failed to initialize GTT\n");
+               ret = -ENODEV;
+               goto out_iomapfree;
+       }
+
+       prealloc_size = dev_priv->mm.gtt->gtt_stolen_entries << PAGE_SHIFT;
+       agp_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT;
+
         dev_priv->mm.gtt_mapping =
-               io_mapping_create_wc(dev->agp->base,
-                                    dev->agp->agp_info.aper_size * 1024*1024);
+               io_mapping_create_wc(dev->agp->base, agp_size);
        if (dev_priv->mm.gtt_mapping == NULL) {
                ret = -EIO;
                goto out_rmmap;
@@ -1934,24 +1948,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
         * MTRR if present.  Even if a UC MTRR isn't present.
         */
        dev_priv->mm.gtt_mtrr = mtrr_add(dev->agp->base,
-                                        dev->agp->agp_info.aper_size *
-                                        1024 * 1024,
+                                        agp_size,
                                         MTRR_TYPE_WRCOMB, 1);
        if (dev_priv->mm.gtt_mtrr < 0) {
                DRM_INFO("MTRR allocation failed.  Graphics "
                         "performance may suffer.\n");
        }
 
-       dev_priv->mm.gtt = intel_gtt_get();
-       if (!dev_priv->mm.gtt) {
-               DRM_ERROR("Failed to initialize GTT\n");
-               ret = -ENODEV;
-               goto out_iomapfree;
-       }
-
-       prealloc_size = dev_priv->mm.gtt->gtt_stolen_entries << PAGE_SHIFT;
-       agp_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT;
-
        /* The i915 workqueue is primarily used for batched retirement of
         * requests (and thus managing bo) once the task has been completed
         * by the GPU. i915_gem_retire_requests() is called directly when we
@@ -1995,7 +1998,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 
        dev->driver->get_vblank_counter = i915_get_vblank_counter;
        dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
-       if (IS_G4X(dev) || IS_IRONLAKE(dev) || IS_GEN6(dev)) {
+       if (IS_G4X(dev) || IS_GEN5(dev) || IS_GEN6(dev)) {
                dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */
                dev->driver->get_vblank_counter = gm45_get_vblank_counter;
        }
@@ -2019,7 +2022,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 
        if (IS_PINEVIEW(dev))
                i915_pineview_get_mem_freq(dev);
-       else if (IS_IRONLAKE(dev))
+       else if (IS_GEN5(dev))
                i915_ironlake_get_mem_freq(dev);
 
        /* On the 945G/GM, the chipset reports the MSI capability on the
@@ -2053,7 +2056,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
        intel_detect_pch(dev);
 
        if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-               ret = i915_load_modeset_init(dev, prealloc_size, agp_size);
+               ret = i915_load_modeset_init(dev);
                if (ret < 0) {
                        DRM_ERROR("failed to init modeset\n");
                        goto out_workqueue_free;
@@ -2079,7 +2082,7 @@ out_workqueue_free:
 out_iomapfree:
        io_mapping_free(dev_priv->mm.gtt_mapping);
 out_rmmap:
-       iounmap(dev_priv->regs);
+       pci_iounmap(dev->pdev, dev_priv->regs);
 put_bridge:
        pci_dev_put(dev_priv->bridge_dev);
 free_priv:
@@ -2096,6 +2099,9 @@ int i915_driver_unload(struct drm_device *dev)
        i915_mch_dev = NULL;
        spin_unlock(&mchdev_lock);
 
+       if (dev_priv->mm.inactive_shrinker.shrink)
+               unregister_shrinker(&dev_priv->mm.inactive_shrinker);
+
        mutex_lock(&dev->struct_mutex);
        ret = i915_gpu_idle(dev);
        if (ret)
@@ -2162,7 +2168,7 @@ int i915_driver_unload(struct drm_device *dev)
        }
 
        if (dev_priv->regs != NULL)
-               iounmap(dev_priv->regs);
+               pci_iounmap(dev->pdev, dev_priv->regs);
 
        intel_teardown_gmbus(dev);
        intel_teardown_mchbar(dev);