Merge branch 'master' of git+ssh://git.freedesktop.org/git/mesa/drm into modesetting-101
authorAlan Hourihane <alanh@tungstengraphics.com>
Tue, 23 Oct 2007 14:34:12 +0000 (15:34 +0100)
committerAlan Hourihane <alanh@tungstengraphics.com>
Tue, 23 Oct 2007 14:34:12 +0000 (15:34 +0100)
1  2 
shared-core/i915_dma.c

diff --combined shared-core/i915_dma.c
  #include "i915_drm.h"
  #include "i915_drv.h"
  
 -#define IS_I965G(dev)  (dev->pci_device == 0x2972 || \
 -                      dev->pci_device == 0x2982 || \
 -                      dev->pci_device == 0x2992 || \
 -                      dev->pci_device == 0x29A2 || \
 -                      dev->pci_device == 0x2A02 || \
 -                      dev->pci_device == 0x2A12)
 -
 -#define IS_G33(dev)    (dev->pci_device == 0x29C2 || \
 -                      dev->pci_device == 0x29B2 || \
 -                      dev->pci_device == 0x29D2) 
 -
  /* Really want an OS-independent resettable timer.  Would like to have
   * this loop run for (eg) 3 sec, but have the timer reset every time
   * the head pointer changes, so that EBUSY only happens if the ring
@@@ -38,8 -49,8 +38,8 @@@
   */
  int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
  {
 -      drm_i915_private_t *dev_priv = dev->dev_private;
 -      drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct drm_i915_ring_buffer *ring = &(dev_priv->ring);
        u32 last_head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
        int i;
  
@@@ -65,8 -76,8 +65,8 @@@
  
  void i915_kernel_lost_context(struct drm_device * dev)
  {
 -      drm_i915_private_t *dev_priv = dev->dev_private;
 -      drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct drm_i915_ring_buffer *ring = &(dev_priv->ring);
  
        ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
        ring->tail = I915_READ(LP_RING + RING_TAIL) & TAIL_ADDR;
                dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY;
  }
  
 -static int i915_dma_cleanup(struct drm_device * dev)
 +int i915_dma_cleanup(struct drm_device * dev)
  {
 +      struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
 +
        /* 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.
        if (dev->irq)
                drm_irq_uninstall(dev);
  
 -      if (dev->dev_private) {
 -              drm_i915_private_t *dev_priv =
 -                  (drm_i915_private_t *) dev->dev_private;
 -
 -              if (dev_priv->ring.virtual_start) {
 -                      drm_core_ioremapfree(&dev_priv->ring.map, dev);
 -              }
 -
 -              if (dev_priv->status_page_dmah) {
 -                      drm_pci_free(dev, dev_priv->status_page_dmah);
 -                      /* 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);
 -              }
 -              drm_free(dev->dev_private, sizeof(drm_i915_private_t),
 -                       DRM_MEM_DRIVER);
 -
 -              dev->dev_private = NULL;
 -      }
 -
        return 0;
  }
  
  static int i915_initialize(struct drm_device * dev,
 -                         drm_i915_private_t * dev_priv,
 -                         drm_i915_init_t * init)
 +                         struct drm_i915_private * dev_priv,
 +                         struct drm_i915_init * init)
  {
 -      memset(dev_priv, 0, sizeof(drm_i915_private_t));
 +      memset(dev_priv, 0, sizeof(struct drm_i915_private));
  
        dev_priv->sarea = drm_getsarea(dev);
        if (!dev_priv->sarea) {
  
  static int i915_dma_resume(struct drm_device * dev)
  {
 -      drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 +      struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
  
        DRM_DEBUG("%s\n", __FUNCTION__);
  
  static int i915_dma_init(struct drm_device *dev, void *data,
                         struct drm_file *file_priv)
  {
 -      drm_i915_private_t *dev_priv;
 -      drm_i915_init_t *init = data;
 +      struct drm_i915_private *dev_priv;
 +      struct drm_i915_init *init = data;
        int retcode = 0;
  
        switch (init->func) {
        case I915_INIT_DMA:
 -              dev_priv = drm_alloc(sizeof(drm_i915_private_t),
 +              dev_priv = drm_alloc(sizeof(struct drm_i915_private),
                                     DRM_MEM_DRIVER);
                if (dev_priv == NULL)
                        return -ENOMEM;
@@@ -329,7 -362,7 +329,7 @@@ static int validate_cmd(int cmd
  static int i915_emit_cmds(struct drm_device * dev, int __user * buffer,
                          int dwords)
  {
 -      drm_i915_private_t *dev_priv = dev->dev_private;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
        int i;
        RING_LOCALS;
  
@@@ -370,7 -403,7 +370,7 @@@ static int i915_emit_box(struct drm_dev
                         struct drm_clip_rect __user * boxes,
                         int i, int DR1, int DR4)
  {
 -      drm_i915_private_t *dev_priv = dev->dev_private;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_clip_rect box;
        RING_LOCALS;
  
  
  void i915_emit_breadcrumb(struct drm_device *dev)
  {
 -      drm_i915_private_t *dev_priv = dev->dev_private;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
        RING_LOCALS;
  
        if (++dev_priv->counter > BREADCRUMB_MASK) {
  
  int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush)
  {
 -      drm_i915_private_t *dev_priv = dev->dev_private;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
        uint32_t flush_cmd = CMD_MI_FLUSH;
        RING_LOCALS;
  
  
  
  static int i915_dispatch_cmdbuffer(struct drm_device * dev,
 -                                 drm_i915_cmdbuffer_t * cmd)
 +                                 struct drm_i915_cmdbuffer * cmd)
  {
  #ifdef I915_HAVE_FENCE
 -      drm_i915_private_t *dev_priv = dev->dev_private;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
  #endif
        int nbox = cmd->num_cliprects;
        int i = 0, count, ret;
  static int i915_dispatch_batchbuffer(struct drm_device * dev,
                                     drm_i915_batchbuffer_t * batch)
  {
 -      drm_i915_private_t *dev_priv = dev->dev_private;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_clip_rect __user *boxes = batch->cliprects;
        int nbox = batch->num_cliprects;
        int i = 0, count;
  
  static void i915_do_dispatch_flip(struct drm_device * dev, int plane, int sync)
  {
 -      drm_i915_private_t *dev_priv = dev->dev_private;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
        u32 num_pages, current_page, next_page, dspbase;
        int shift = 2 * plane, x, y;
        RING_LOCALS;
  
  void i915_dispatch_flip(struct drm_device * dev, int planes, int sync)
  {
 -      drm_i915_private_t *dev_priv = dev->dev_private;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
        int i;
  
        DRM_DEBUG("%s: planes=0x%x pfCurrentPage=%d\n",
  
  static int i915_quiescent(struct drm_device * dev)
  {
 -      drm_i915_private_t *dev_priv = dev->dev_private;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
  
        i915_kernel_lost_context(dev);
        return i915_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__);
@@@ -637,7 -670,7 +637,7 @@@ static int i915_flush_ioctl(struct drm_
  static int i915_batchbuffer(struct drm_device *dev, void *data,
                            struct drm_file *file_priv)
  {
 -      drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 +      struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
        drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
            dev_priv->sarea_priv;
        drm_i915_batchbuffer_t *batch = data;
  static int i915_cmdbuffer(struct drm_device *dev, void *data,
                          struct drm_file *file_priv)
  {
 -      drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 -      drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
 +      struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
 +      struct drm_i915_sarea *sarea_priv = (struct drm_i915_sarea *)
            dev_priv->sarea_priv;
 -      drm_i915_cmdbuffer_t *cmdbuf = data;
 +      struct drm_i915_cmdbuffer *cmdbuf = data;
        int ret;
  
        DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n",
@@@ -772,7 -805,9 +772,9 @@@ int i915_process_relocs(struct drm_fil
  
        memset(&reloc_kmap, 0, sizeof(reloc_kmap));
  
+       mutex_lock(&dev->struct_mutex);
        reloc_list_object = drm_lookup_buffer_object(file_priv, cur_handle, 1);
+       mutex_unlock(&dev->struct_mutex);
        if (!reloc_list_object)
                return -EINVAL;
  
@@@ -838,6 -873,43 +840,43 @@@ out
        return ret;
  }
  
+ static int i915_exec_reloc(struct drm_file *file_priv, drm_handle_t buf_handle,
+                          drm_handle_t buf_reloc_handle,
+                          struct drm_buffer_object **buffers,
+                          uint32_t buf_count)
+ {
+       struct drm_device *dev = file_priv->head->dev;
+       struct i915_relocatee_info relocatee;
+       int ret = 0;
+       memset(&relocatee, 0, sizeof(relocatee));
+       
+       mutex_lock(&dev->struct_mutex);
+       relocatee.buf = drm_lookup_buffer_object(file_priv, buf_handle, 1);
+       mutex_unlock(&dev->struct_mutex);
+       if (!relocatee.buf) {
+               DRM_DEBUG("relocatee buffer invalid %08x\n", buf_handle);
+               ret = -EINVAL;
+               goto out_err;
+       }
+       
+       while (buf_reloc_handle) {
+               ret = i915_process_relocs(file_priv, buf_handle, &buf_reloc_handle, &relocatee, buffers, buf_count);
+               if (ret) {
+                       DRM_ERROR("process relocs failed\n");
+                       break;
+               }
+       }
+       
+       drm_bo_kunmap(&relocatee.kmap);
+       mutex_lock(&dev->struct_mutex);
+       drm_bo_usage_deref_locked(&relocatee.buf);
+       mutex_unlock(&dev->struct_mutex);
+       
+ out_err:
+       return ret;
+ }
  /*
   * Validate, add fence and relocate a block of bos from a userspace list
   */
@@@ -854,7 -926,7 +893,7 @@@ int i915_validate_buffer_list(struct dr
        unsigned buf_count = 0;
        struct drm_device *dev = file_priv->head->dev;
        uint32_t buf_reloc_handle, buf_handle;
-       struct i915_relocatee_info relocatee;
  
        do {
                if (buf_count >= *num_buffers) {
  
                if (arg.handled) {
                        data = arg.next;
+                       mutex_lock(&dev->struct_mutex);
                        buffers[buf_count] = drm_lookup_buffer_object(file_priv, req->arg_handle, 1);
+                       mutex_unlock(&dev->struct_mutex);
                        buf_count++;
                        continue;
                }
                buf_count++;
  
                if (buf_reloc_handle) {
-                       memset(&relocatee, 0, sizeof(relocatee));
-                       relocatee.buf = drm_lookup_buffer_object(file_priv, buf_handle, 1);
-                       if (!relocatee.buf) {
-                               DRM_DEBUG("relocatee buffer invalid %08x\n", buf_handle);
-                               ret = -EINVAL;
-                               goto out_err;
-                       }
-                       while (buf_reloc_handle) {
-                               ret = i915_process_relocs(file_priv, buf_handle, &buf_reloc_handle, &relocatee, buffers, buf_count);
-                               if (ret) {
-                                       DRM_ERROR("process relocs failed\n");
-                                       break;
-                               }
-                       }
-                       drm_bo_kunmap(&relocatee.kmap);
-                       mutex_lock(&dev->struct_mutex);
-                       drm_bo_usage_deref_locked(&relocatee.buf);
-                       mutex_unlock(&dev->struct_mutex);
+                       ret = i915_exec_reloc(file_priv, buf_handle, buf_reloc_handle, buffers, buf_count);
                        if (ret)
                                goto out_err;
                }
        } while (next != 0);
        *num_buffers = buf_count;
@@@ -953,11 -1005,11 +972,11 @@@ out_err
  static int i915_execbuffer(struct drm_device *dev, void *data,
                           struct drm_file *file_priv)
  {
 -      drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 +      struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
        drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
                dev_priv->sarea_priv;
        struct drm_i915_execbuffer *exec_buf = data;
 -      struct _drm_i915_batchbuffer *batch = &exec_buf->batch;
 +      struct drm_i915_batchbuffer *batch = &exec_buf->batch;
        struct drm_fence_arg *fence_arg = &exec_buf->fence_arg;
        int num_buffers;
        int ret;
        if (ret)
                goto out_free;
  
+       /* make sure all previous memory operations have passed */
+       asm volatile("mfence":::"memory");
        /* submit buffer */
        batch->start = buffers[num_buffers-1]->offset;
  
@@@ -1033,14 -1088,14 +1055,14 @@@ out_free
  }
  #endif
  
 -static int i915_do_cleanup_pageflip(struct drm_device * dev)
 +int i915_do_cleanup_pageflip(struct drm_device * dev)
  {
 -      drm_i915_private_t *dev_priv = dev->dev_private;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
        int i, planes, num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2;
  
        DRM_DEBUG("%s\n", __FUNCTION__);
  
 -      for (i = 0, planes = 0; i < 2; i++)
 +      for (i = 0, planes = 0; i < 2; i++) {
                if (dev_priv->sarea_priv->pf_current_page & (0x3 << (2 * i))) {
                        dev_priv->sarea_priv->pf_current_page =
                                (dev_priv->sarea_priv->pf_current_page &
  
                        planes |= 1 << i;
                }
 +      }
  
        if (planes)
                i915_dispatch_flip(dev, planes, 0);
  
  static int i915_flip_bufs(struct drm_device *dev, void *data, struct drm_file *file_priv)
  {
 -      drm_i915_flip_t *param = data;
 +      struct drm_i915_flip *param = data;
  
        DRM_DEBUG("%s\n", __FUNCTION__);
  
  static int i915_getparam(struct drm_device *dev, void *data,
                         struct drm_file *file_priv)
  {
 -      drm_i915_private_t *dev_priv = dev->dev_private;
 -      drm_i915_getparam_t *param = data;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct drm_i915_getparam *param = data;
        int value;
  
        if (!dev_priv) {
  static int i915_setparam(struct drm_device *dev, void *data,
                         struct drm_file *file_priv)
  {
 -      drm_i915_private_t *dev_priv = dev->dev_private;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
        drm_i915_setparam_t *param = data;
  
        if (!dev_priv) {
@@@ -1155,7 -1209,7 +1177,7 @@@ static int i915_mmio(struct drm_device 
                     struct drm_file *file_priv)
  {
        uint32_t buf[8];
 -      drm_i915_private_t *dev_priv = dev->dev_private;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
        drm_i915_mmio_entry_t *e;        
        drm_i915_mmio_t *mmio = data;
        void __iomem *base;
  static int i915_set_status_page(struct drm_device *dev, void *data,
                                struct drm_file *file_priv)
  {
 -      drm_i915_private_t *dev_priv = dev->dev_private;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
        drm_i915_hws_addr_t *hws = data;
  
        if (!dev_priv) {
        dev_priv->hw_status_page = dev_priv->hws_map.handle;
  
        memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
 -      I915_WRITE(0x02080, dev_priv->status_gfx_addr);
 +      I915_WRITE(I915REG_HWS_PGA, dev_priv->status_gfx_addr);
        DRM_DEBUG("load hws 0x2080 with gfx mem 0x%x\n",
                        dev_priv->status_gfx_addr);
        DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page);
        return 0;
  }
  
 -int i915_driver_load(struct drm_device *dev, unsigned long flags)
 -{
 -      /* i915 has 4 more counters */
 -      dev->counters += 4;
 -      dev->types[6] = _DRM_STAT_IRQ;
 -      dev->types[7] = _DRM_STAT_PRIMARY;
 -      dev->types[8] = _DRM_STAT_SECONDARY;
 -      dev->types[9] = _DRM_STAT_DMA;
 -
 -      return 0;
 -}
 -
 -void i915_driver_lastclose(struct drm_device * dev)
 -{
 -      if (dev->dev_private) {
 -              drm_i915_private_t *dev_priv = dev->dev_private;
 -              i915_do_cleanup_pageflip(dev);
 -              i915_mem_takedown(&(dev_priv->agp_heap));
 -      }
 -      i915_dma_cleanup(dev);
 -}
 -
 -void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
 -{
 -      if (dev->dev_private) {
 -              drm_i915_private_t *dev_priv = dev->dev_private;
 -              i915_mem_release(dev, file_priv, dev_priv->agp_heap);
 -      }
 -}
 -
  struct drm_ioctl_desc i915_ioctls[] = {
        DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
        DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH),
@@@ -1279,4 -1363,10 +1301,4 @@@ int i915_driver_device_is_agp(struct dr
        return 1;
  }
  
 -int i915_driver_firstopen(struct drm_device *dev)
 -{
 -#ifdef I915_HAVE_BUFFER
 -      drm_bo_driver_init(dev);
 -#endif
 -      return 0;
 -}
 +