Merge remote branch 'origin/master' into modesetting-101
authorDave Airlie <airlied@redhat.com>
Fri, 25 Jan 2008 05:27:53 +0000 (15:27 +1000)
committerDave Airlie <airlied@redhat.com>
Fri, 25 Jan 2008 05:27:53 +0000 (15:27 +1000)
Conflicts:

linux-core/drm_bo.c
linux-core/drm_drv.c
shared-core/drm.h
shared-core/i915_dma.c
shared-core/i915_drv.h
shared-core/i915_irq.c
shared-core/radeon_irq.c

29 files changed:
1  2 
libdrm/xf86drm.c
linux-core/ati_pcigart.c
linux-core/drmP.h
linux-core/drm_agpsupport.c
linux-core/drm_bo.c
linux-core/drm_bo_move.c
linux-core/drm_drv.c
linux-core/drm_object.c
linux-core/drm_objects.h
linux-core/drm_vm.c
linux-core/i810_dma.c
linux-core/i915_buffer.c
linux-core/i915_drv.c
linux-core/radeon_buffer.c
linux-core/radeon_drv.c
linux-core/radeon_ms_drv.c
shared-core/drm.h
shared-core/drm_pciids.txt
shared-core/i915_dma.c
shared-core/i915_drm.h
shared-core/i915_drv.h
shared-core/i915_irq.c
shared-core/i915_mem.c
shared-core/radeon_cp.c
shared-core/radeon_drv.h
shared-core/radeon_irq.c
shared-core/radeon_ms.h
shared-core/radeon_ms_bo.c
shared-core/radeon_ms_drm.c

Simple merge
Simple merge
Simple merge
Simple merge
@@@ -1543,10 -1645,9 +1644,9 @@@ int drm_bo_handle_validate(struct drm_f
                           struct drm_bo_info_rep *rep,
                           struct drm_buffer_object **bo_rep)
  {
 -      struct drm_device *dev = file_priv->head->dev;
 +      struct drm_device *dev = file_priv->minor->dev;
        struct drm_buffer_object *bo;
        int ret;
-       int no_wait = hint & DRM_BO_HINT_DONT_BLOCK;
  
        mutex_lock(&dev->struct_mutex);
        bo = drm_lookup_buffer_object(file_priv, handle, 1);
@@@ -1649,7 -1749,7 +1748,7 @@@ int drm_buffer_object_create(struct drm
        size += buffer_start & ~PAGE_MASK;
        num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
        if (num_pages == 0) {
-               DRM_ERROR("Illegal buffer object size %d.\n", size);
 -              DRM_ERROR("Illegal buffer object size.\n");
++              DRM_ERROR("Illegal buffer object size %ld.\n", size);
                return -EINVAL;
        }
  
@@@ -1752,13 -1859,21 +1858,21 @@@ int drm_bo_create_ioctl(struct drm_devi
                return -EINVAL;
        }
  
-       bo_type = (req->buffer_start) ? drm_bo_type_user : drm_bo_type_dc;
+       /*
+        * If the buffer creation request comes in with a starting address,
+        * that points at the desired user pages to map. Otherwise, create
+        * a drm_bo_type_device buffer, which uses pages allocated from the kernel
+        */
+       bo_type = (req->buffer_start) ? drm_bo_type_user : drm_bo_type_device;
  
+       /*
+        * User buffers cannot be shared
+        */
        if (bo_type == drm_bo_type_user)
-               req->mask &= ~DRM_BO_FLAG_SHAREABLE;
+               req->flags &= ~DRM_BO_FLAG_SHAREABLE;
  
 -      ret = drm_buffer_object_create(file_priv->head->dev,
 +      ret = drm_buffer_object_create(file_priv->minor->dev,
-                                      req->size, bo_type, req->mask,
+                                      req->size, bo_type, req->flags,
                                       req->hint, req->page_alignment,
                                       req->buffer_start, &entry);
        if (ret)
Simple merge
@@@ -116,21 -116,11 +116,26 @@@ static struct drm_ioctl_desc drm_ioctls
        DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
        DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
        DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0),
+       DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
        DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
 +      DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW),
 +      DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW),
 +      DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETOUTPUT, drm_mode_getoutput, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW),
 +      DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW),
 +      DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW),
 +      DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW),
 +      DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW),
 +
 +      DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_output_property_set_ioctl, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW),
 +      DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW),
 +      DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW),
 +      DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW),
 +      DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_ROOT_ONLY | DRM_CONTROL_ALLOW),
 +
++
        DRM_IOCTL_DEF(DRM_IOCTL_MM_INIT, drm_mm_init_ioctl,
                      DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
        DRM_IOCTL_DEF(DRM_IOCTL_MM_TAKEDOWN, drm_mm_takedown_ioctl,
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -537,12 -536,12 +537,11 @@@ static struct drm_driver driver = 
         */
        .driver_features =
            DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR | */
-           DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL |
-           DRIVER_IRQ_VBL2,
+           DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
        .load = i915_driver_load,
        .unload = i915_driver_unload,
 -      .firstopen = i915_driver_firstopen,
 -      .lastclose = i915_driver_lastclose,
 -      .preclose = i915_driver_preclose,
 +/*    .lastclose = i915_driver_lastclose,
 +      .preclose = i915_driver_preclose, */
        .suspend = i915_suspend,
        .resume = i915_resume,
        .device_is_agp = i915_driver_device_is_agp,
index 8e2b20b,0000000..5dff189
mode 100644,000000..100644
--- /dev/null
@@@ -1,263 -1,0 +1,263 @@@
- uint32_t radeon_evict_mask(struct drm_buffer_object *bo)
 +/**************************************************************************
 + * 
 + * Copyright 2007 Dave Airlie
 + * All Rights Reserved.
 + * 
 + * Permission is hereby granted, free of charge, to any person obtaining a
 + * copy of this software and associated documentation files (the
 + * "Software"), to deal in the Software without restriction, including
 + * without limitation the rights to use, copy, modify, merge, publish,
 + * distribute, sub license, and/or sell copies of the Software, and to
 + * permit persons to whom the Software is furnished to do so, subject to
 + * the following conditions:
 + * 
 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
 + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
 + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 
 + * USE OR OTHER DEALINGS IN THE SOFTWARE.
 + *
 + * The above copyright notice and this permission notice (including the
 + * next paragraph) shall be included in all copies or substantial portions
 + * of the Software.
 + * 
 + * 
 + **************************************************************************/
 +/*
 + * Authors: Dave Airlie <airlied@linux.ie>
 + */
 +
 +#include "drmP.h"
 +#include "radeon_drm.h"
 +#include "radeon_drv.h"
 +
 +struct drm_ttm_backend *radeon_create_ttm_backend_entry(struct drm_device * dev)
 +{
 +      drm_radeon_private_t *dev_priv = dev->dev_private;
 +
 +      if(dev_priv->flags & RADEON_IS_AGP)
 +              return drm_agp_init_ttm(dev);
 +      else
 +              return ati_pcigart_init_ttm(dev, &dev_priv->gart_info, radeon_gart_flush);
 +}
 +
 +int radeon_fence_types(struct drm_buffer_object *bo, uint32_t * class, uint32_t * type)
 +{
 +      *class = 0;
 +      if (bo->mem.flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE))
 +              *type = 3;
 +      else
 +              *type = 1;
 +      return 0;
 +}
 +
 +int radeon_invalidate_caches(struct drm_device * dev, uint64_t flags)
 +{
 +      drm_radeon_private_t *dev_priv = dev->dev_private;
 +      RING_LOCALS;
 +
 +      BEGIN_RING(4);
 +      RADEON_FLUSH_CACHE();
 +      RADEON_FLUSH_ZCACHE();
 +      ADVANCE_RING();
 +      return 0;
 +}
 +
-       tmp_mem.mask = DRM_BO_FLAG_MEM_TT |
++uint64_t radeon_evict_flags(struct drm_buffer_object *bo)
 +{
 +      switch (bo->mem.mem_type) {
 +      case DRM_BO_MEM_LOCAL:
 +      case DRM_BO_MEM_TT:
 +              return DRM_BO_FLAG_MEM_LOCAL;
 +      case DRM_BO_MEM_VRAM:
 +              if (bo->mem.num_pages > 128)
 +                      return DRM_BO_MEM_TT;
 +              else
 +                      return DRM_BO_MEM_LOCAL;
 +      default:
 +              return DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_CACHED;
 +      }
 +}
 +
 +int radeon_init_mem_type(struct drm_device * dev, uint32_t type,
 +                       struct drm_mem_type_manager * man)
 +{
 +      drm_radeon_private_t *dev_priv = dev->dev_private;
 +
 +      switch (type) {
 +      case DRM_BO_MEM_LOCAL:
 +              man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
 +                  _DRM_FLAG_MEMTYPE_CACHED;
 +              man->drm_bus_maptype = 0;
 +              break;
 +      case DRM_BO_MEM_VRAM:
 +              man->flags =  _DRM_FLAG_MEMTYPE_FIXED | _DRM_FLAG_MEMTYPE_MAPPABLE | _DRM_FLAG_NEEDS_IOREMAP;
 +              man->io_addr = NULL;
 +              man->drm_bus_maptype = _DRM_FRAME_BUFFER;
 +              man->io_offset = drm_get_resource_start(dev, 0);
 +              man->io_size = drm_get_resource_len(dev, 0);
 +              break;
 +      case DRM_BO_MEM_TT:
 +              if (dev_priv->flags & RADEON_IS_AGP) {
 +                      if (!(drm_core_has_AGP(dev) && dev->agp)) {
 +                              DRM_ERROR("AGP is not enabled for memory type %u\n",
 +                                        (unsigned)type);
 +                              return -EINVAL;
 +                      }
 +                      man->io_offset = dev->agp->agp_info.aper_base;
 +                      man->io_size = dev->agp->agp_info.aper_size * 1024 * 1024;
 +                      man->io_addr = NULL;
 +                      man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
 +                              _DRM_FLAG_MEMTYPE_CSELECT | _DRM_FLAG_NEEDS_IOREMAP;
 +                      man->drm_bus_maptype = _DRM_AGP;
 +              } else {
 +                      man->io_offset = dev_priv->gart_vm_start;
 +                      man->io_size = dev_priv->gart_size;
 +                      man->io_addr = NULL;
 +                      man->flags = _DRM_FLAG_MEMTYPE_CSELECT | _DRM_FLAG_MEMTYPE_MAPPABLE | _DRM_FLAG_MEMTYPE_CMA;
 +                      man->drm_bus_maptype = _DRM_SCATTER_GATHER;
 +              }
 +              break;
 +      default:
 +              DRM_ERROR("Unsupported memory type %u\n", (unsigned)type);
 +              return -EINVAL;
 +      }
 +      return 0;
 +}
 +
 +static void radeon_emit_copy_blit(struct drm_device * dev,
 +                                uint32_t src_offset,
 +                                uint32_t dst_offset,
 +                                uint32_t pages, int direction)
 +{
 +      uint32_t cur_pages;
 +      uint32_t stride = PAGE_SIZE;
 +      drm_radeon_private_t *dev_priv = dev->dev_private;
 +      uint32_t format, height;
 +      RING_LOCALS;
 +
 +      if (!dev_priv)
 +              return;
 +
 +      /* 32-bit copy format */
 +      format = RADEON_COLOR_FORMAT_ARGB8888;
 +
 +      /* radeon limited to 16k stride */
 +      stride &= 0x3fff;
 +      while(pages > 0) {
 +              cur_pages = pages;
 +              if (cur_pages > 2048)
 +                      cur_pages = 2048;
 +              pages -= cur_pages;
 +
 +              /* needs verification */
 +              BEGIN_RING(7);          
 +              OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT_MULTI, 5));
 +              OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
 +                       RADEON_GMC_DST_PITCH_OFFSET_CNTL |
 +                       RADEON_GMC_BRUSH_NONE |
 +                       (format << 8) |
 +                       RADEON_GMC_SRC_DATATYPE_COLOR |
 +                       RADEON_ROP3_S |
 +                       RADEON_DP_SRC_SOURCE_MEMORY |
 +                       RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS);
 +              if (direction) {
 +                      OUT_RING((stride << 22) | (src_offset >> 10));
 +                      OUT_RING((stride << 22) | (dst_offset >> 10));
 +              } else {
 +                      OUT_RING((stride << 22) | (dst_offset >> 10));
 +                      OUT_RING((stride << 22) | (src_offset >> 10));
 +              }
 +              OUT_RING(0);
 +              OUT_RING(pages); /* x - y */
 +              OUT_RING((stride << 16) | cur_pages);
 +              ADVANCE_RING();
 +      }
 +
 +      BEGIN_RING(2);
 +      RADEON_WAIT_UNTIL_2D_IDLE();
 +      ADVANCE_RING();
 +
 +      return;
 +}
 +
 +static int radeon_move_blit(struct drm_buffer_object * bo,
 +                          int evict, int no_wait, struct drm_bo_mem_reg *new_mem)
 +{
 +      struct drm_bo_mem_reg *old_mem = &bo->mem;
 +      int dir = 0;
 +
 +      if ((old_mem->mem_type == new_mem->mem_type) &&
 +          (new_mem->mm_node->start <
 +           old_mem->mm_node->start + old_mem->mm_node->size)) {
 +              dir = 1;
 +      }
 +
 +      radeon_emit_copy_blit(bo->dev,
 +                            old_mem->mm_node->start << PAGE_SHIFT,
 +                            new_mem->mm_node->start << PAGE_SHIFT,
 +                            new_mem->num_pages, dir);
 +
 +      
 +      return drm_bo_move_accel_cleanup(bo, evict, no_wait, 0,
 +                                       DRM_FENCE_TYPE_EXE |
 +                                       DRM_RADEON_FENCE_TYPE_RW,
 +                                       DRM_RADEON_FENCE_FLAG_FLUSHED, new_mem);
 +}
 +
 +static int radeon_move_flip(struct drm_buffer_object * bo,
 +                          int evict, int no_wait, struct drm_bo_mem_reg * new_mem)
 +{
 +      struct drm_device *dev = bo->dev;
 +      struct drm_bo_mem_reg tmp_mem;
 +      int ret;
 +
 +      tmp_mem = *new_mem;
 +      tmp_mem.mm_node = NULL;
-       ret = drm_bind_ttm(bo->ttm, &tmp_mem);
++      tmp_mem.flags = DRM_BO_FLAG_MEM_TT |
 +          DRM_BO_FLAG_CACHED | DRM_BO_FLAG_FORCE_CACHING;
 +
 +      ret = drm_bo_mem_space(bo, &tmp_mem, no_wait);
 +      if (ret)
 +              return ret;
 +
++      ret = drm_ttm_bind(bo->ttm, &tmp_mem);
 +      if (ret)
 +              goto out_cleanup;
 +
 +      ret = radeon_move_blit(bo, 1, no_wait, &tmp_mem);
 +      if (ret)
 +              goto out_cleanup;
 +
 +      ret = drm_bo_move_ttm(bo, evict, no_wait, new_mem);
 +out_cleanup:
 +      if (tmp_mem.mm_node) {
 +              mutex_lock(&dev->struct_mutex);
 +              if (tmp_mem.mm_node != bo->pinned_node)
 +                      drm_mm_put_block(tmp_mem.mm_node);
 +              tmp_mem.mm_node = NULL;
 +              mutex_unlock(&dev->struct_mutex);
 +      }
 +      return ret;
 +}
 +
 +int radeon_move(struct drm_buffer_object * bo,
 +              int evict, int no_wait, struct drm_bo_mem_reg * new_mem)
 +{
 +      struct drm_bo_mem_reg *old_mem = &bo->mem;
 +
 +      DRM_DEBUG("\n");
 +      if (old_mem->mem_type == DRM_BO_MEM_LOCAL) {
 +              return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
 +      } else if (new_mem->mem_type == DRM_BO_MEM_LOCAL) {
 +              if (radeon_move_flip(bo, evict, no_wait, new_mem))
 +                      return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
 +      } else {
 +              if (radeon_move_blit(bo, evict, no_wait, new_mem))
 +                      return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
 +      }
 +      return 0;
 +}
 +
@@@ -56,38 -56,6 +56,38 @@@ static struct pci_device_id pciidlist[
        radeon_PCI_IDS
  };
  
-       .evict_mask = radeon_evict_mask,
 +
 +#ifdef RADEON_HAVE_FENCE
 +static struct drm_fence_driver radeon_fence_driver = {
 +      .num_classes = 1,
 +      .wrap_diff = (1 << 30),
 +      .flush_diff = (1 << 29),
 +      .sequence_mask = 0xffffffffU,
 +      .lazy_capable = 1,
 +      .emit = radeon_fence_emit_sequence,
 +      .poke_flush = radeon_poke_flush,
 +      .has_irq = radeon_fence_has_irq,
 +};
 +#endif
 +#ifdef RADEON_HAVE_BUFFER
 +
 +static uint32_t radeon_mem_prios[] = {DRM_BO_MEM_VRAM, DRM_BO_MEM_TT, DRM_BO_MEM_LOCAL};
 +static uint32_t radeon_busy_prios[] = {DRM_BO_MEM_TT, DRM_BO_MEM_VRAM, DRM_BO_MEM_LOCAL};
 +
 +static struct drm_bo_driver radeon_bo_driver = {
 +      .mem_type_prio = radeon_mem_prios,
 +      .mem_busy_prio = radeon_busy_prios,
 +      .num_mem_type_prio = sizeof(radeon_mem_prios)/sizeof(uint32_t),
 +      .num_mem_busy_prio = sizeof(radeon_busy_prios)/sizeof(uint32_t),
 +      .create_ttm_backend_entry = radeon_create_ttm_backend_entry,
 +      .fence_type = radeon_fence_types,
 +      .invalidate_caches = radeon_invalidate_caches,
 +      .init_mem_type = radeon_init_mem_type,
++      .evict_flags = radeon_evict_flags,
 +      .move = radeon_move,
 +};
 +#endif
 +
  static int probe(struct pci_dev *pdev, const struct pci_device_id *ent);
  static struct drm_driver driver = {
        .driver_features =
index 4b52a7d,0000000..d7b0eec
mode 100644,000000..100644
--- /dev/null
@@@ -1,146 -1,0 +1,143 @@@
-       .vblank_wait = NULL,
-       .vblank_wait2 = NULL,
 +/*
 + * Copyright 2007 Jerome Glisse.
 + * All Rights Reserved.
 + *
 + * Permission is hereby granted, free of charge, to any person obtaining a
 + * copy of this software and associated documentation files (the "Software"),
 + * to deal in the Software without restriction, including without limitation
 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 + * and/or sell copies of the Software, and to permit persons to whom the
 + * Software is furnished to do so, subject to the following conditions:
 + *
 + * The above copyright notice and this permission notice (including the next
 + * paragraph) shall be included in all copies or substantial portions of the
 + * Software.
 + *
 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 + * DEALINGS IN THE SOFTWARE.
 + */
 +/*
 + * Authors:
 + *    Jerome Glisse <glisse@freedesktop.org>
 + */
 +#include "drm_pciids.h"
 +#include "radeon_ms.h"
 +
 +extern struct drm_fence_driver radeon_ms_fence_driver;
 +extern struct drm_bo_driver radeon_ms_bo_driver;
 +extern struct drm_ioctl_desc radeon_ms_ioctls[];
 +extern int radeon_ms_num_ioctls;
 +
 +static int radeon_ms_driver_dri_library_name(struct drm_device * dev,
 +                                           char * buf);
 +static int radeon_ms_driver_probe(struct pci_dev *pdev,
 +                                const struct pci_device_id *ent);
 +
 +static struct pci_device_id pciidlist[] = {
 +      radeon_ms_PCI_IDS
 +};
 +
 +static struct drm_driver driver = {
 +      .load = radeon_ms_driver_load,
 +      .firstopen = NULL,
 +      .open = radeon_ms_driver_open,
 +      .preclose = NULL,
 +      .postclose = NULL,
 +      .lastclose = radeon_ms_driver_lastclose,
 +      .unload = radeon_ms_driver_unload,
 +      .dma_ioctl = radeon_ms_driver_dma_ioctl,
 +      .dma_ready = NULL,
 +      .dma_quiescent = NULL,
 +      .context_ctor = NULL,
 +      .context_dtor = NULL,
 +      .kernel_context_switch = NULL,
 +      .kernel_context_switch_unlock = NULL,
-           DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED |
-           DRIVER_IRQ_VBL | DRIVER_IRQ_VBL2,
 +      .dri_library_name = radeon_ms_driver_dri_library_name,
 +      .device_is_agp = NULL,
 +      .irq_handler = radeon_ms_irq_handler,
 +      .irq_preinstall = radeon_ms_irq_preinstall,
 +      .irq_postinstall = radeon_ms_irq_postinstall,
 +      .irq_uninstall = radeon_ms_irq_uninstall,
 +      .reclaim_buffers = drm_core_reclaim_buffers,
 +      .reclaim_buffers_locked = NULL,
 +      .reclaim_buffers_idlelocked = NULL,
 +      .get_map_ofs = drm_core_get_map_ofs,
 +      .get_reg_ofs = drm_core_get_reg_ofs,
 +      .set_version = NULL,
 +      .fb_probe = radeonfb_probe,
 +      .fb_remove = radeonfb_remove,
 +      .fence_driver = &radeon_ms_fence_driver,
 +      .bo_driver = &radeon_ms_bo_driver,
 +      .major = DRIVER_MAJOR,
 +      .minor = DRIVER_MINOR,
 +      .patchlevel = DRIVER_PATCHLEVEL,
 +      .name = DRIVER_NAME,
 +      .desc = DRIVER_DESC,
 +      .date = DRIVER_DATE,
 +      .driver_features =
 +          DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
++          DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED,
 +      .dev_priv_size = 0, 
 +      .ioctls = radeon_ms_ioctls,
 +      .num_ioctls = 0,
 +      .fops = {
 +              .owner = THIS_MODULE,
 +              .open = drm_open,
 +              .release = drm_release,
 +              .ioctl = drm_ioctl,
 +              .mmap = drm_mmap,
 +              .poll = drm_poll,
 +              .fasync = drm_fasync,
 +#if defined(CONFIG_COMPAT) && LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)
 +              .compat_ioctl = radeon_ms_compat_ioctl,
 +#endif
 +              },
 +      .pci_driver = {
 +              .name = DRIVER_NAME,
 +              .id_table = pciidlist,
 +              .probe = radeon_ms_driver_probe,
 +              .remove = __devexit_p(drm_cleanup_pci),
 +      },
 +};
 +
 +static int radeon_ms_driver_probe(struct pci_dev *pdev,
 +                                const struct pci_device_id *ent)
 +{
 +      return drm_get_dev(pdev, ent, &driver);
 +}
 +
 +static int radeon_ms_driver_dri_library_name(struct drm_device * dev,
 +                                           char * buf)
 +{
 +      struct drm_radeon_private *dev_priv = dev->dev_private;
 +      int ret;
 +
 +      switch (dev_priv->family) {
 +      default:
 +              ret = snprintf(buf, PAGE_SIZE, "\n");
 +      }
 +      return ret;
 +}
 +
 +static void __exit radeon_ms_driver_exit(void)
 +{
 +      drm_exit(&driver);
 +}
 +
 +static int __init radeon_ms_driver_init(void)
 +{
 +      driver.num_ioctls = radeon_ms_num_ioctls;
 +      return drm_init(&driver, pciidlist);
 +}
 +
 +module_init(radeon_ms_driver_init);
 +module_exit(radeon_ms_driver_exit);
 +
 +MODULE_AUTHOR(DRIVER_AUTHOR);
 +MODULE_DESCRIPTION(DRIVER_DESC);
 +MODULE_LICENSE("GPL and additional rights");
@@@ -1118,21 -1042,6 +1176,21 @@@ struct drm_mode_mode_cmd 
  #define DRM_IOCTL_BO_WAIT_IDLE          DRM_IOWR(0xd5, struct drm_bo_map_wait_idle_arg)
  #define DRM_IOCTL_BO_VERSION          DRM_IOR(0xd6, struct drm_bo_version_arg)
  
 +#define DRM_IOCTL_MODE_GETRESOURCES     DRM_IOWR(0xA0, struct drm_mode_card_res)
 +#define DRM_IOCTL_MODE_GETCRTC          DRM_IOWR(0xA1, struct drm_mode_crtc)
 +#define DRM_IOCTL_MODE_GETOUTPUT        DRM_IOWR(0xA2, struct drm_mode_get_output)
 +#define DRM_IOCTL_MODE_SETCRTC          DRM_IOWR(0xA3, struct drm_mode_crtc)
 +#define DRM_IOCTL_MODE_ADDFB            DRM_IOWR(0xA4, struct drm_mode_fb_cmd)
 +#define DRM_IOCTL_MODE_RMFB             DRM_IOWR(0xA5, unsigned int)
 +#define DRM_IOCTL_MODE_GETFB            DRM_IOWR(0xA6, struct drm_mode_fb_cmd)
 +
 +#define DRM_IOCTL_MODE_SETPROPERTY     DRM_IOWR(0xA7, struct drm_mode_output_set_property)
 +#define DRM_IOCTL_MODE_GETPROPBLOB     DRM_IOWR(0xA8, struct drm_mode_get_blob)
 +#define DRM_IOCTL_MODE_ATTACHMODE      DRM_IOWR(0xA9, struct drm_mode_mode_cmd)
 +#define DRM_IOCTL_MODE_DETACHMODE      DRM_IOWR(0xAA, struct drm_mode_mode_cmd)
 +
 +#define DRM_IOCTL_MODE_GETPROPERTY     DRM_IOWR(0xAB, struct drm_mode_get_property)
++
  /*@}*/
  
  /**
Simple merge
@@@ -926,9 -938,9 +917,9 @@@ int i915_validate_buffer_list(struct dr
        unsigned long next = 0;
        int ret = 0;
        unsigned buf_count = 0;
 -      struct drm_device *dev = file_priv->head->dev;
 +      struct drm_device *dev = file_priv->minor->dev;
-       uint32_t buf_reloc_handle, buf_handle;
+       uint32_t buf_handle;
+       uint32_t __user *reloc_user_ptr;
  
        do {
                if (buf_count >= *num_buffers) {
Simple merge
@@@ -283,11 -267,13 +280,14 @@@ extern int i915_vblank_pipe_set(struct 
  extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
                                struct drm_file *file_priv);
  extern int i915_emit_irq(struct drm_device * dev);
- extern void i915_user_irq_on(struct drm_i915_private *dev_priv);
- extern void i915_user_irq_off(struct drm_i915_private *dev_priv);
 +extern void i915_enable_interrupt (struct drm_device *dev);
+ extern int i915_enable_vblank(struct drm_device *dev, int crtc);
+ extern void i915_disable_vblank(struct drm_device *dev, int crtc);
+ extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc);
  extern int i915_vblank_swap(struct drm_device *dev, void *data,
                            struct drm_file *file_priv);
 -extern void i915_user_irq_on(drm_i915_private_t *dev_priv);
 -extern void i915_user_irq_off(drm_i915_private_t *dev_priv);
++extern void i915_user_irq_on(struct drm_i915_private *dev_priv);
++extern void i915_user_irq_off(struct drm_i915_private *dev_priv);
  
  /* i915_mem.c */
  extern int i915_mem_alloc(struct drm_device *dev, void *data,
@@@ -61,6 -58,44 +61,44 @@@ i915_get_pipe(struct drm_device *dev, i
  }
  
  /**
 -      drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+  * i915_get_plane - return the the plane associated with a given pipe
+  * @dev: DRM device
+  * @pipe: pipe to look for
+  *
+  * The Intel Mesa & 2D drivers call the vblank routines with a plane number
+  * rather than a plane number, since they may not always be equal.  This routine
+  * maps the given @pipe back to a plane number.
+  */
+ static int
+ i915_get_plane(struct drm_device *dev, int pipe)
+ {
+       if (i915_get_pipe(dev, 0) == pipe)
+               return 0;
+       return 1;
+ }
+ /**
+  * i915_pipe_enabled - check if a pipe is enabled
+  * @dev: DRM device
+  * @pipe: pipe to check
+  *
+  * Reading certain registers when the pipe is disabled can hang the chip.
+  * Use this routine to make sure the PLL is running and the pipe is active
+  * before reading such registers if unsure.
+  */
+ static int
+ i915_pipe_enabled(struct drm_device *dev, int pipe)
+ {
++      struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
+       unsigned long pipeconf = pipe ? PIPEBCONF : PIPEACONF;
+       if (I915_READ(pipeconf) & PIPEACONF_ENABLE)
+               return 1;
+       return 0;
+ }
+ /**
   * Emit a synchronous flip.
   *
   * This function must be called with the drawable spinlock held.
@@@ -114,13 -149,12 +152,12 @@@ i915_dispatch_vsync_flip(struct drm_dev
   */
  static void i915_vblank_tasklet(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;
        struct list_head *list, *tmp, hits, *hit;
        int nhits, nrects, slice[2], upper[2], lower[2], i, num_pages;
-       unsigned counter[2] = { atomic_read(&dev->vbl_received),
-                               atomic_read(&dev->vbl_received2) };
+       unsigned counter[2];
        struct drm_drawable_info *drw;
 -      drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
 +      struct drm_i915_sarea *sarea_priv = dev_priv->sarea_priv;
        u32 cpp = dev_priv->cpp,  offsets[3];
        u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD |
                                XY_SRC_COPY_BLT_WRITE_ALPHA |
                drm_free(swap_hit, sizeof(*swap_hit), DRM_MEM_DRIVER);
        }
  }
 -      drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ #if 0
+ static int i915_in_vblank(struct drm_device *dev, int pipe)
+ {
 -      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;
+       unsigned long pipedsl, vblank, vtotal;
+       unsigned long vbl_start, vbl_end, cur_line;
+       pipedsl = pipe ? PIPEBDSL : PIPEADSL;
+       vblank = pipe ? VBLANK_B : VBLANK_A;
+       vtotal = pipe ? VTOTAL_B : VTOTAL_A;
+       vbl_start = I915_READ(vblank) & VBLANK_START_MASK;
+       vbl_end = (I915_READ(vblank) >> VBLANK_END_SHIFT) & VBLANK_END_MASK;
+       cur_line = I915_READ(pipedsl);
+       if (cur_line >= vbl_start)
+               return 1;
+       return 0;
+ }
+ #endif
+ u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
+ {
++      struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
+       unsigned long high_frame;
+       unsigned long low_frame;
+       u32 high1, high2, low, count;
+       int pipe;
+       pipe = i915_get_pipe(dev, plane);
+       high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH;
+       low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
+       if (!i915_pipe_enabled(dev, pipe)) {
+           printk(KERN_ERR "trying to get vblank count for disabled "
+                  "pipe %d\n", pipe);
+           return 0;
+       }
+       /*
+        * High & low register fields aren't synchronized, so make sure
+        * we get a low value that's stable across two reads of the high
+        * register.
+        */
+       do {
+               high1 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
+                        PIPE_FRAME_HIGH_SHIFT);
+               low =  ((I915_READ(low_frame) & PIPE_FRAME_LOW_MASK) >>
+                       PIPE_FRAME_LOW_SHIFT);
+               high2 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
+                        PIPE_FRAME_HIGH_SHIFT);
+       } while (high1 != high2);
+       count = (high1 << 8) | low;
+       /*
+        * If we're in the middle of the vblank period, the
+        * above regs won't have been updated yet, so return
+        * an incremented count to stay accurate
+        */
+ #if 0
+       if (i915_in_vblank(dev, pipe))
+               count++;
+ #endif
+       return count;
+ }
  
 +#define HOTPLUG_CMD_CRT 1
 +#define HOTPLUG_CMD_SDVOB 4
 +#define HOTPLUG_CMD_SDVOC 8
 +
 +static struct drm_device *hotplug_dev;
 +static int hotplug_cmd = 0;
 +static spinlock_t hotplug_lock = SPIN_LOCK_UNLOCKED;
 +
 +static void i915_hotplug_crt(struct drm_device *dev)
 +{
 +      struct drm_output *output;
 +      struct intel_output *iout;
 +
 +      mutex_lock(&dev->mode_config.mutex);
 +
 +      /* find the crt output */
 +      list_for_each_entry(output, &dev->mode_config.output_list, head) {
 +              iout = output->driver_private;
 +              if (iout->type == INTEL_OUTPUT_ANALOG)
 +                      break;
 +              else
 +                      iout = 0;
 +      }
 +
 +      if (iout == 0)
 +              goto unlock;
 +
 +      drm_hotplug_stage_two(dev, output);
 +
 +unlock:
 +      mutex_unlock(&dev->mode_config.mutex);
 +}
 +
 +static void i915_hotplug_sdvo(struct drm_device *dev, int sdvoB)
 +{
 +      struct drm_output *output = 0;
 +      enum drm_output_status status;
 +
 +      mutex_lock(&dev->mode_config.mutex);
 +
 +      output = intel_sdvo_find(dev, sdvoB);
 +
 +      if (!output) {
 +              DRM_ERROR("could not find sdvo%s output\n", sdvoB ? "B" : "C");
 +              goto unlock;
 +      }
 +
 +      status = output->funcs->detect(output);
 +
 +      if (status != output_status_connected)
 +              DRM_DEBUG("disconnect or unkown we don't do anything then\n");
 +      else
 +              drm_hotplug_stage_two(dev, output);
 +
 +      /* wierd hw bug, sdvo stop sending interupts */
 +      intel_sdvo_set_hotplug(output, 1);
 +
 +unlock:
 +      mutex_unlock(&dev->mode_config.mutex);
 +}
 +/*
 + * This code is called in a more safe envirmoent to handle the hotplugs.
 + * Add code here for hotplug love to userspace.
 + */
 +static void i915_hotplug_work_func(struct work_struct *work)
 +{
 +      struct drm_device *dev = hotplug_dev;
 +      int crt;
 +      int sdvoB;
 +      int sdvoC;
 +
 +      spin_lock(&hotplug_lock);
 +      crt = hotplug_cmd & HOTPLUG_CMD_CRT;
 +      sdvoB = hotplug_cmd & HOTPLUG_CMD_SDVOB;
 +      sdvoC = hotplug_cmd & HOTPLUG_CMD_SDVOC;
 +      hotplug_cmd = 0;
 +      spin_unlock(&hotplug_lock);
 +
 +      if (crt)
 +              i915_hotplug_crt(dev);
 +
 +      if (sdvoB)
 +              i915_hotplug_sdvo(dev, 1);
 +
 +      if (sdvoC)
 +              i915_hotplug_sdvo(dev, 0);
 +
 +}
 +
 +static int i915_run_hotplug_tasklet(struct drm_device *dev, uint32_t stat)
 +{
 +      static DECLARE_WORK(hotplug, i915_hotplug_work_func);
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +
 +      hotplug_dev = dev;
 +
 +      if (stat & CRT_HOTPLUG_INT_STATUS) {
 +              DRM_DEBUG("CRT event\n");
 +
 +              if (stat & CRT_HOTPLUG_MONITOR_MASK) {
 +                      spin_lock(&hotplug_lock);
 +                      hotplug_cmd |= HOTPLUG_CMD_CRT;
 +                      spin_unlock(&hotplug_lock);
 +              } else {
 +                      /* handle crt disconnects */
 +              }
 +      }
 +
 +      if (stat & SDVOB_HOTPLUG_INT_STATUS) {
 +              DRM_DEBUG("sDVOB event\n");
 +
 +              spin_lock(&hotplug_lock);
 +              hotplug_cmd |= HOTPLUG_CMD_SDVOB;
 +              spin_unlock(&hotplug_lock);
 +      }
 +
 +      if (stat & SDVOC_HOTPLUG_INT_STATUS) {
 +              DRM_DEBUG("sDVOC event\n");
 +
 +              spin_lock(&hotplug_lock);
 +              hotplug_cmd |= HOTPLUG_CMD_SDVOC;
 +              spin_unlock(&hotplug_lock);
 +      }
 +
 +      queue_work(dev_priv->wq, &hotplug);
 +
 +      return 0;
 +}
 +
  irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
  {
        struct drm_device *dev = (struct drm_device *) arg;
        pipea_stats = I915_READ(I915REG_PIPEASTAT);
        pipeb_stats = I915_READ(I915REG_PIPEBSTAT);
  
 -      temp = I915_READ16(I915REG_INT_IDENTITY_R);
 +      /* On i8xx hw the IIR and IER are 16bit on i9xx its 32bit */
-       if (IS_I9XX(dev)) {
++      if (IS_I9XX(dev))
 +              temp = I915_READ(I915REG_INT_IDENTITY_R);
-       } else {
++      else
 +              temp = I915_READ16(I915REG_INT_IDENTITY_R);
-       }
 +
 +      temp2 = temp;
 +      temp &= (dev_priv->irq_enable_reg | USER_INT_FLAG);
  
  #if 0
-       DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp);
 +      /* ugly despamification of pipeb event irq */
 +      if (temp & (0xFFFFFFF ^ ((1 << 5) | (1 << 7)))) {
 +              DRM_DEBUG("IIR %08x\n", temp2);
 +              DRM_DEBUG("MSK %08x\n", dev_priv->irq_enable_reg | USER_INT_FLAG);
 +              DRM_DEBUG("M&I %08x\n", temp);
 +              DRM_DEBUG("HOT %08x\n", I915_READ(PORT_HOTPLUG_STAT));
 +      }
 +#else
 +#if 0
+       DRM_DEBUG("flag=%08x\n", temp);
  #endif
 +#endif
 +
        if (temp == 0)
                return IRQ_NONE;
  
 +      if (IS_I9XX(dev)) {
 +              I915_WRITE(I915REG_INT_IDENTITY_R, temp);
 +              (void) I915_READ(I915REG_INT_IDENTITY_R);
 +      } else {
 +              I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
 +              (void) I915_READ16(I915REG_INT_IDENTITY_R);
 +      }
 +
+       /*
+        * Clear the PIPE(A|B)STAT regs before the IIR otherwise
+        * we may get extra interrupts.
+        */
+       if (temp & VSYNC_PIPEA_FLAG) {
+               drm_handle_vblank(dev, i915_get_plane(dev, 0));
+               I915_WRITE(I915REG_PIPEASTAT,
+                          pipea_stats | I915_VBLANK_INTERRUPT_ENABLE |
+                          I915_VBLANK_CLEAR);
+       }
++
+       if (temp & VSYNC_PIPEB_FLAG) {
+               drm_handle_vblank(dev, i915_get_plane(dev, 1));
+               I915_WRITE(I915REG_PIPEBSTAT,
+                          pipeb_stats | I915_VBLANK_INTERRUPT_ENABLE |
+                          I915_VBLANK_CLEAR);
+       }
+       I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
+       (void) I915_READ16(I915REG_INT_IDENTITY_R); /* Flush posted write */
 +      DRM_READMEMORYBARRIER();
 +
+       temp &= (dev_priv->irq_enable_reg | USER_INT_FLAG | VSYNC_PIPEA_FLAG |
+                VSYNC_PIPEB_FLAG);
        dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
  
        if (temp & USER_INT_FLAG) {
        }
  
        if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) {
-               int vblank_pipe = dev_priv->vblank_pipe;
-               if ((vblank_pipe &
-                    (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B))
-                   == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) {
-                       if (temp & VSYNC_PIPEA_FLAG)
-                               atomic_inc(&dev->vbl_received);
-                       if (temp & VSYNC_PIPEB_FLAG)
-                               atomic_inc(&dev->vbl_received2);
-               } else if (((temp & VSYNC_PIPEA_FLAG) &&
-                           (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) ||
-                          ((temp & VSYNC_PIPEB_FLAG) &&
-                           (vblank_pipe & DRM_I915_VBLANK_PIPE_B)))
-                       atomic_inc(&dev->vbl_received);
-               DRM_WAKEUP(&dev->vbl_queue);
-               drm_vbl_send_signals(dev);
                if (dev_priv->swaps_pending > 0)
                        drm_locked_tasklet(dev, i915_vblank_tasklet);
-               I915_WRITE(I915REG_PIPEASTAT,
-                       pipea_stats|I915_VBLANK_INTERRUPT_ENABLE|
-                       I915_VBLANK_CLEAR);
-               I915_WRITE(I915REG_PIPEBSTAT,
-                       pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE|
-                       I915_VBLANK_CLEAR);
        }
  
 +      /* for now lest just ack it */
 +      if (temp & (1 << 17)) {
 +              DRM_DEBUG("Hotplug event received\n");
 +
 +              temp2 = I915_READ(PORT_HOTPLUG_STAT);
 +
 +              i915_run_hotplug_tasklet(dev, temp2);
 +
 +              I915_WRITE(PORT_HOTPLUG_STAT,temp2);
 +      }
 +
        return IRQ_HANDLED;
  }
  
  int i915_emit_irq(struct drm_device *dev)
  {
-       
 -      drm_i915_private_t *dev_priv = dev->dev_private;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
        RING_LOCALS;
  
        i915_kernel_lost_context(dev);
@@@ -577,10 -510,10 +683,10 @@@ void i915_user_irq_off(struct drm_i915_
  
  static int i915_wait_irq(struct drm_device * dev, int irq_nr)
  {
 -      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;
        int ret = 0;
  
-       DRM_DEBUG("%s irq_nr=%d breadcrumb=%d\n", __FUNCTION__, irq_nr,
+       DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr,
                  READ_BREADCRUMB(dev_priv));
  
        if (READ_BREADCRUMB(dev_priv) >= irq_nr)
@@@ -690,64 -564,68 +737,103 @@@ int i915_irq_emit(struct drm_device *de
  int i915_irq_wait(struct drm_device *dev, void *data,
                  struct drm_file *file_priv)
  {
 -      drm_i915_private_t *dev_priv = dev->dev_private;
 -      drm_i915_irq_wait_t *irqwait = data;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct drm_i915_irq_wait *irqwait = data;
  
        if (!dev_priv) {
-               DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+               DRM_ERROR("called with no initialization\n");
                return -EINVAL;
        }
  
        return i915_wait_irq(dev, irqwait->irq_seq);
  }
  
void i915_enable_interrupt (struct drm_device *dev)
int i915_enable_vblank(struct drm_device *dev, int plane)
  {
 -      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;
-       struct drm_output *o;
+       int pipe = i915_get_pipe(dev, plane);
 -
 +      
-       dev_priv->irq_enable_reg = USER_INT_FLAG; 
-       if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
+       switch (pipe) {
+       case 0:
                dev_priv->irq_enable_reg |= VSYNC_PIPEA_FLAG;
-       if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
+               break;
+       case 1:
                dev_priv->irq_enable_reg |= VSYNC_PIPEB_FLAG;
 -      drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+               break;
+       default:
+               DRM_ERROR("tried to enable vblank on non-existent pipe %d\n",
+                         pipe);
+               break;
+       }
+       I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
+       return 0;
+ }
+ void i915_disable_vblank(struct drm_device *dev, int plane)
+ {
 -static void i915_enable_interrupt (struct drm_device *dev)
++      struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
+       int pipe = i915_get_pipe(dev, plane);
+       switch (pipe) {
+       case 0:
+               dev_priv->irq_enable_reg &= ~VSYNC_PIPEA_FLAG;
+               break;
+       case 1:
+               dev_priv->irq_enable_reg &= ~VSYNC_PIPEB_FLAG;
+               break;
+       default:
+               DRM_ERROR("tried to disable vblank on non-existent pipe %d\n",
+                         pipe);
+               break;
+       }
+       I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
+ }
 -      drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 -      
++void i915_enable_interrupt (struct drm_device *dev)
+ {
++      struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
++      struct drm_output *o;
++
+       dev_priv->irq_enable_reg |= USER_INT_FLAG;
  
 -      I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
 +      if (IS_I9XX(dev) && dev->mode_config.num_output) {
 +              dev_priv->irq_enable_reg |= HOTPLUG_FLAG;
 +
 +              /* Activate the CRT */
 +              I915_WRITE(PORT_HOTPLUG_EN, CRT_HOTPLUG_INT_EN);
 +
 +              /* SDVOB */
 +              o = intel_sdvo_find(dev, 1);
 +              if (o && intel_sdvo_supports_hotplug(o)) {
 +                      intel_sdvo_set_hotplug(o, 1);
 +                      I915_WRITE(PORT_HOTPLUG_EN, SDVOB_HOTPLUG_INT_EN);
 +              }
 +
 +              /* SDVOC */
 +              o = intel_sdvo_find(dev, 0);
 +              if (o && intel_sdvo_supports_hotplug(o)) {
 +                      intel_sdvo_set_hotplug(o, 1);
 +                      I915_WRITE(PORT_HOTPLUG_EN, SDVOC_HOTPLUG_INT_EN);
 +              }
 +
 +      }
 +
 +      if (IS_I9XX(dev)) {
 +              I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
 +      } else {
 +              I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
 +      }
 +
 +      DRM_DEBUG("HEN %08x\n",I915_READ(PORT_HOTPLUG_EN));
 +      DRM_DEBUG("HST %08x\n",I915_READ(PORT_HOTPLUG_STAT));
 +      DRM_DEBUG("IER %08x\n",I915_READ(I915REG_INT_ENABLE_R));
 +      DRM_DEBUG("SDB %08x\n",I915_READ(SDVOB));
 +
 +      I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
 +
        dev_priv->irq_enabled = 1;
  }
  
  int i915_vblank_pipe_set(struct drm_device *dev, void *data,
                         struct drm_file *file_priv)
  {
 -      drm_i915_private_t *dev_priv = dev->dev_private;
 -      drm_i915_vblank_pipe_t *pipe = data;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct drm_i915_vblank_pipe *pipe = data;
  
        if (!dev_priv) {
-               DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+               DRM_ERROR("called with no initialization\n");
                return -EINVAL;
        }
  
@@@ -949,22 -832,17 +1040,23 @@@ int i915_vblank_swap(struct drm_device 
  */
  void i915_driver_irq_preinstall(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;
  
        I915_WRITE16(I915REG_HWSTAM, 0xeffe);
 -      I915_WRITE16(I915REG_INT_MASK_R, 0x0);
 -      I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
 +      if (IS_I9XX(dev)) {
 +              I915_WRITE(I915REG_INT_MASK_R, 0x0);
 +              I915_WRITE(I915REG_INT_ENABLE_R, 0x0);
 +      } else {
 +              I915_WRITE16(I915REG_INT_MASK_R, 0x0);
 +              I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
 +      }
 +
  }
  
void i915_driver_irq_postinstall(struct drm_device * dev)
int i915_driver_irq_postinstall(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;
+       int ret, num_pipes = 2;
  
        DRM_SPININIT(&dev_priv->swaps_lock, "swap");
        INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
Simple merge
Simple merge
@@@ -371,16 -373,15 +380,16 @@@ extern void radeon_mem_release(struct d
                                /* radeon_irq.c */
  extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv);
  extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv);
 +extern int radeon_emit_irq(struct drm_device * dev);
  
  extern void radeon_do_release(struct drm_device * dev);
- extern int radeon_driver_vblank_wait(struct drm_device * dev,
                                   unsigned int *sequence);
- extern int radeon_driver_vblank_wait2(struct drm_device * dev,
                                    unsigned int *sequence);
+ extern u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc);
extern int radeon_enable_vblank(struct drm_device *dev, int crtc);
+ extern void radeon_disable_vblank(struct drm_device *dev, int crtc);
extern void radeon_do_release(struct drm_device * dev);
  extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS);
  extern void radeon_driver_irq_preinstall(struct drm_device * dev);
- extern void radeon_driver_irq_postinstall(struct drm_device * dev);
+ extern int radeon_driver_irq_postinstall(struct drm_device * dev);
  extern void radeon_driver_irq_uninstall(struct drm_device * dev);
  extern int radeon_vblank_crtc_get(struct drm_device *dev);
  extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value);
@@@ -405,30 -406,6 +414,30 @@@ extern int r300_do_cp_cmdbuf(struct drm
                             struct drm_file *file_priv,
                             drm_radeon_kcmd_buffer_t *cmdbuf);
  
- extern uint32_t radeon_evict_mask(struct drm_buffer_object *bo);
 +
 +#ifdef RADEON_HAVE_FENCE
 +/* i915_fence.c */
 +
 +
 +extern void radeon_fence_handler(struct drm_device *dev);
 +extern int radeon_fence_emit_sequence(struct drm_device *dev, uint32_t class,
 +                                    uint32_t flags, uint32_t *sequence, 
 +                                  uint32_t *native_type);
 +extern void radeon_poke_flush(struct drm_device *dev, uint32_t class);
 +extern int radeon_fence_has_irq(struct drm_device *dev, uint32_t class, uint32_t flags);
 +#endif
 +
 +#ifdef RADEON_HAVE_BUFFER
 +/* radeon_buffer.c */
 +extern struct drm_ttm_backend *radeon_create_ttm_backend_entry(struct drm_device *dev);
 +extern int radeon_fence_types(struct drm_buffer_object *bo, uint32_t *class, uint32_t *type);
 +extern int radeon_invalidate_caches(struct drm_device *dev, uint64_t buffer_flags);
++extern uint64_t radeon_evict_flags(struct drm_buffer_object *bo);
 +extern int radeon_init_mem_type(struct drm_device * dev, uint32_t type,
 +                              struct drm_mem_type_manager * man);
 +extern int radeon_move(struct drm_buffer_object * bo,
 +                     int evict, int no_wait, struct drm_bo_mem_reg * new_mem);
 +#endif
  /* Flags for stats.boxes
   */
  #define RADEON_BOX_DMA_IDLE      0x1
@@@ -81,33 -128,14 +128,17 @@@ irqreturn_t radeon_driver_irq_handler(D
        stat &= dev_priv->irq_enable_reg;
  
        /* SW interrupt */
 -      if (stat & RADEON_SW_INT_TEST)
 -              DRM_WAKEUP(&dev_priv->swi_queue);
 -
 +      if (stat & RADEON_SW_INT_TEST) {
 +              DRM_WAKEUP(&dev_priv->irq_queue);
 +#ifdef RADEON_HAVE_FENCE
 +              radeon_fence_handler(dev);
 +#endif
 +      }
        /* VBLANK interrupt */
-       if (stat & (RADEON_CRTC_VBLANK_STAT|RADEON_CRTC2_VBLANK_STAT)) {
-               int vblank_crtc = dev_priv->vblank_crtc;
-               if ((vblank_crtc &
-                    (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) ==
-                   (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) {
-                       if (stat & RADEON_CRTC_VBLANK_STAT)
-                               atomic_inc(&dev->vbl_received);
-                       if (stat & RADEON_CRTC2_VBLANK_STAT)
-                               atomic_inc(&dev->vbl_received2);
-               } else if (((stat & RADEON_CRTC_VBLANK_STAT) &&
-                          (vblank_crtc & DRM_RADEON_VBLANK_CRTC1)) ||
-                          ((stat & RADEON_CRTC2_VBLANK_STAT) &&
-                           (vblank_crtc & DRM_RADEON_VBLANK_CRTC2)))
-                       atomic_inc(&dev->vbl_received);
-               DRM_WAKEUP(&dev->vbl_queue);
-               drm_vbl_send_signals(dev);
-       }
+       if (stat & RADEON_CRTC_VBLANK_STAT)
+               drm_handle_vblank(dev, 0);
+       if (stat & RADEON_CRTC2_VBLANK_STAT)
+               drm_handle_vblank(dev, 1);
  
        return IRQ_HANDLED;
  }
@@@ -271,11 -256,20 +258,20 @@@ int radeon_driver_irq_postinstall(struc
  {
        drm_radeon_private_t *dev_priv =
            (drm_radeon_private_t *) dev->dev_private;
+       int ret;
  
 -      atomic_set(&dev_priv->swi_emitted, 0);
 -      DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
 +      dev_priv->counter = 0;
 +      DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
  
-       radeon_enable_interrupt(dev);
+       ret = drm_vblank_init(dev, 2);
+       if (ret)
+               return ret;
+       dev->max_vblank_count = 0x001fffff;
+       radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
+       return 0;
  }
  
  void radeon_driver_irq_uninstall(struct drm_device * dev)
index a784882,0000000..6653383
mode 100644,000000..100644
--- /dev/null
@@@ -1,607 -1,0 +1,607 @@@
- uint32_t radeon_ms_evict_mask(struct drm_buffer_object *bo);
 +/*
 + * Copyright 2007 Jérôme Glisse
 + * Copyright 2007 Dave Airlie
 + * Copyright 2007 Alex Deucher
 + * All Rights Reserved.
 + *
 + * Permission is hereby granted, free of charge, to any person obtaining a
 + * copy of this software and associated documentation files (the "Software"),
 + * to deal in the Software without restriction, including without limitation
 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 + * and/or sell copies of the Software, and to permit persons to whom the
 + * Software is furnished to do so, subject to the following conditions:
 + *
 + * The above copyright notice and this permission notice (including the next
 + * paragraph) shall be included in all copies or substantial portions of the
 + * Software.
 + *
 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 + * DEALINGS IN THE SOFTWARE.
 + */
 +/*
 + * Authors:
 + *    Jérôme Glisse <glisse@freedesktop.org>
 + */
 +#ifndef __RADEON_MS_H__
 +#define __RADEON_MS_H__
 +
 +#include "radeon_ms_drv.h"
 +#include "radeon_ms_reg.h"
 +#include "radeon_ms_drm.h"
 +#include "radeon_ms_rom.h"
 +#include "radeon_ms_properties.h"
 +
 +#define DRIVER_AUTHOR      "Jerome Glisse, Dave Airlie,  Gareth Hughes, "\
 +                         "Keith Whitwell, others."
 +#define DRIVER_NAME        "radeon_ms"
 +#define DRIVER_DESC        "radeon kernel modesetting"
 +#define DRIVER_DATE        "20071108"
 +#define DRIVER_MAJOR        1
 +#define DRIVER_MINOR        0
 +#define DRIVER_PATCHLEVEL   0
 +
 +enum radeon_bus_type {
 +      RADEON_PCI = 0x10000,
 +      RADEON_AGP = 0x20000,
 +      RADEON_PCIE = 0x30000,
 +};
 +
 +enum radeon_family {
 +      CHIP_R100,
 +      CHIP_RV100,
 +      CHIP_RS100,
 +      CHIP_RV200,
 +      CHIP_RS200,
 +      CHIP_R200,
 +      CHIP_RV250,
 +      CHIP_RS300,
 +      CHIP_RV280,
 +      CHIP_R300,
 +      CHIP_R350,
 +      CHIP_R360,
 +      CHIP_RV350,
 +      CHIP_RV370,
 +      CHIP_RV380,
 +      CHIP_RS400,
 +      CHIP_RV410,
 +      CHIP_R420,
 +      CHIP_R430,
 +      CHIP_R480,
 +      CHIP_LAST,
 +};
 +
 +enum radeon_monitor_type {
 +      MT_UNKNOWN = -1,
 +      MT_NONE    = 0,
 +      MT_CRT     = 1,
 +      MT_LCD     = 2,
 +      MT_DFP     = 3,
 +      MT_CTV     = 4,
 +      MT_STV     = 5
 +};
 +
 +enum radeon_connector_type {
 +      CONNECTOR_NONE,
 +      CONNECTOR_PROPRIETARY,
 +      CONNECTOR_VGA,
 +      CONNECTOR_DVI_I,
 +      CONNECTOR_DVI_D,
 +      CONNECTOR_CTV,
 +      CONNECTOR_STV,
 +      CONNECTOR_UNSUPPORTED
 +};
 +
 +enum radeon_output_type {
 +      OUTPUT_NONE,
 +      OUTPUT_DAC1,
 +      OUTPUT_DAC2,
 +      OUTPUT_TMDS,
 +      OUTPUT_LVDS
 +};
 +
 +struct radeon_state;
 +
 +struct radeon_ms_crtc {
 +      int             crtc;
 +      uint16_t        lut_r[256];
 +      uint16_t        lut_g[256];
 +      uint16_t        lut_b[256];
 +};
 +
 +struct radeon_ms_i2c {
 +      struct drm_device           *drm_dev;
 +      uint32_t                    reg;
 +      struct i2c_adapter          adapter;
 +      struct i2c_algo_bit_data    algo;
 +};
 +
 +struct radeon_ms_connector {
 +      struct radeon_ms_i2c    *i2c;
 +      struct edid             *edid;
 +      struct drm_output       *output;
 +      int                     type;
 +      int                     monitor_type;
 +      int                     crtc;
 +      uint32_t                i2c_reg;
 +      char                    outputs[RADEON_MAX_OUTPUTS];
 +      char                    name[32];
 +};
 +
 +struct radeon_ms_output {
 +      int                         type;
 +      struct drm_device           *dev;
 +      struct radeon_ms_connector  *connector;
 +      int (*initialize)(struct radeon_ms_output *output);
 +      enum drm_output_status (*detect)(struct radeon_ms_output *output);
 +      void (*dpms)(struct radeon_ms_output *output, int mode);
 +      int (*get_modes)(struct radeon_ms_output *output);
 +      bool (*mode_fixup)(struct radeon_ms_output *output,
 +                      struct drm_display_mode *mode,
 +                      struct drm_display_mode *adjusted_mode);
 +      int (*mode_set)(struct radeon_ms_output *output,
 +                      struct drm_display_mode *mode,
 +                      struct drm_display_mode *adjusted_mode);
 +      void (*restore)(struct radeon_ms_output *output,
 +                      struct radeon_state *state);
 +      void (*save)(struct radeon_ms_output *output,
 +                      struct radeon_state *state);
 +};
 +
 +struct radeon_state {
 +      /* memory */
 +      uint32_t        config_aper_0_base;
 +      uint32_t        config_aper_1_base;
 +      uint32_t        config_aper_size;
 +      uint32_t        mc_fb_location;
 +      uint32_t        display_base_addr;
 +      /* irq */
 +      uint32_t        gen_int_cntl;
 +      /* pci */
 +      uint32_t        aic_ctrl;
 +      uint32_t        aic_pt_base;
 +      uint32_t        aic_pt_base_lo;
 +      uint32_t        aic_pt_base_hi;
 +      uint32_t        aic_lo_addr;
 +      uint32_t        aic_hi_addr;
 +      /* agp */
 +      uint32_t        agp_cntl;
 +      uint32_t        agp_command;
 +      uint32_t        agp_base;
 +      uint32_t        agp_base_2;
 +      uint32_t        bus_cntl;
 +      uint32_t        mc_agp_location;
 +      /* cp */
 +      uint32_t        cp_rb_cntl;
 +      uint32_t        cp_rb_base;
 +      uint32_t        cp_rb_rptr_addr;
 +      uint32_t        cp_rb_wptr;
 +      uint32_t        cp_rb_wptr_delay;
 +      uint32_t        scratch_umsk;
 +      uint32_t        scratch_addr;
 +      /* pcie */
 +      uint32_t        pcie_tx_gart_cntl;
 +      uint32_t        pcie_tx_gart_discard_rd_addr_lo;
 +      uint32_t        pcie_tx_gart_discard_rd_addr_hi;
 +      uint32_t        pcie_tx_gart_base;
 +      uint32_t        pcie_tx_gart_start_lo;
 +      uint32_t        pcie_tx_gart_start_hi;
 +      uint32_t        pcie_tx_gart_end_lo;
 +      uint32_t        pcie_tx_gart_end_hi;
 +      /* surface */
 +      uint32_t        surface_cntl;
 +      uint32_t        surface0_info;
 +      uint32_t        surface0_lower_bound;
 +      uint32_t        surface0_upper_bound;
 +      uint32_t        surface1_info;
 +      uint32_t        surface1_lower_bound;
 +      uint32_t        surface1_upper_bound;
 +      uint32_t        surface2_info;
 +      uint32_t        surface2_lower_bound;
 +      uint32_t        surface2_upper_bound;
 +      uint32_t        surface3_info;
 +      uint32_t        surface3_lower_bound;
 +      uint32_t        surface3_upper_bound;
 +      uint32_t        surface4_info;
 +      uint32_t        surface4_lower_bound;
 +      uint32_t        surface4_upper_bound;
 +      uint32_t        surface5_info;
 +      uint32_t        surface5_lower_bound;
 +      uint32_t        surface5_upper_bound;
 +      uint32_t        surface6_info;
 +      uint32_t        surface6_lower_bound;
 +      uint32_t        surface6_upper_bound;
 +      uint32_t        surface7_info;
 +      uint32_t        surface7_lower_bound;
 +      uint32_t        surface7_upper_bound;
 +      /* crtc */
 +      uint32_t        crtc_gen_cntl;
 +      uint32_t        crtc_ext_cntl;
 +      uint32_t        crtc_h_total_disp;
 +      uint32_t        crtc_h_sync_strt_wid;
 +      uint32_t        crtc_v_total_disp;
 +      uint32_t        crtc_v_sync_strt_wid;
 +      uint32_t        crtc_offset;
 +      uint32_t        crtc_offset_cntl;
 +      uint32_t        crtc_pitch;
 +      uint32_t        crtc_more_cntl;
 +      uint32_t        crtc_tile_x0_y0;
 +      uint32_t        fp_h_sync_strt_wid;
 +      uint32_t        fp_v_sync_strt_wid;
 +      uint32_t        fp_crtc_h_total_disp;
 +      uint32_t        fp_crtc_v_total_disp;
 +      /* pll */
 +      uint32_t        clock_cntl_index;
 +      uint32_t        ppll_cntl;
 +      uint32_t        ppll_ref_div;
 +      uint32_t        ppll_div_0;
 +      uint32_t        ppll_div_1;
 +      uint32_t        ppll_div_2;
 +      uint32_t        ppll_div_3;
 +      uint32_t        vclk_ecp_cntl;
 +      uint32_t        htotal_cntl;
 +      /* dac */
 +      uint32_t        dac_cntl;
 +      uint32_t        dac_cntl2;
 +      uint32_t        dac_ext_cntl;
 +      uint32_t        disp_misc_cntl;
 +      uint32_t        dac_macro_cntl;
 +      uint32_t        disp_pwr_man;
 +      uint32_t        disp_merge_cntl;
 +      uint32_t        disp_output_cntl;
 +      uint32_t        disp2_merge_cntl;
 +      uint32_t        dac_embedded_sync_cntl;
 +      uint32_t        dac_broad_pulse;
 +      uint32_t        dac_skew_clks;
 +      uint32_t        dac_incr;
 +      uint32_t        dac_neg_sync_level;
 +      uint32_t        dac_pos_sync_level;
 +      uint32_t        dac_blank_level;
 +      uint32_t        dac_sync_equalization;
 +      uint32_t        tv_dac_cntl;
 +      uint32_t        tv_master_cntl;
 +};
 +
 +struct drm_radeon_private {
 +      /* driver family specific functions */
 +      int (*bus_finish)(struct drm_device *dev);
 +      int (*bus_init)(struct drm_device *dev);
 +      void (*bus_restore)(struct drm_device *dev, struct radeon_state *state);
 +      void (*bus_save)(struct drm_device *dev, struct radeon_state *state);
 +      struct drm_ttm_backend *(*create_ttm)(struct drm_device *dev);
 +      void (*irq_emit)(struct drm_device *dev);
 +      void (*flush_cache)(struct drm_device *dev);
 +      /* bus informations */
 +      void                        *bus;
 +      uint32_t                    bus_type;
 +      /* cp */
 +      uint32_t                    ring_buffer_size;
 +      uint32_t                    ring_rptr;
 +      uint32_t                    ring_wptr;
 +      uint32_t                    ring_mask;
 +      int                         ring_free;
 +      uint32_t                    ring_tail_mask;
 +      uint32_t                    write_back_area_size;
 +      struct drm_buffer_object    *ring_buffer_object;
 +      struct drm_bo_kmap_obj      ring_buffer_map;
 +      uint32_t                    *ring_buffer;
 +      uint32_t                    *write_back_area;
 +      const uint32_t              *microcode;
 +      /* card family */
 +      uint32_t                    usec_timeout;
 +      uint32_t                    family;
 +      struct radeon_ms_output     *outputs[RADEON_MAX_OUTPUTS];
 +      struct radeon_ms_connector  *connectors[RADEON_MAX_CONNECTORS];
 +      /* drm map (MMIO, FB) */
 +      struct drm_map              mmio;
 +      struct drm_map              vram;
 +      /* gpu address space */
 +      uint32_t                    gpu_vram_size;
 +      uint32_t                    gpu_vram_start;
 +      uint32_t                    gpu_vram_end;
 +      uint32_t                    gpu_gart_size;
 +      uint32_t                    gpu_gart_start;
 +      uint32_t                    gpu_gart_end;
 +      /* state of the card when module was loaded */
 +      struct radeon_state         load_state;
 +      /* state the driver wants */
 +      struct radeon_state         driver_state;
 +      /* last emitted fence */
 +      uint32_t                    fence_id_last;
 +      uint32_t                    fence_reg;
 +      /* when doing gpu stop we save here current state */
 +      uint32_t                    crtc_ext_cntl;
 +      uint32_t                    crtc_gen_cntl;
 +      uint32_t                    crtc2_gen_cntl;
 +      uint32_t                    ov0_scale_cntl;
 +      /* bool & type on the hw */
 +      uint8_t                     crtc1_dpms;
 +      uint8_t                     crtc2_dpms;
 +      uint8_t                     restore_state;
 +      uint8_t                     cp_ready;
 +      uint8_t                     bus_ready;
 +      uint8_t                     write_back;
 +      /* abstract asic specific structures */
 +      struct radeon_ms_rom        rom;
 +      struct radeon_ms_properties properties;
 +};
 +
 +
 +/* radeon_ms_bo.c */
 +int radeon_ms_bo_get_gpu_addr(struct drm_device *dev,
 +                            struct drm_bo_mem_reg *mem,
 +                            uint32_t *gpu_addr);
 +int radeon_ms_bo_move(struct drm_buffer_object * bo, int evict,
 +                    int no_wait, struct drm_bo_mem_reg * new_mem);
 +struct drm_ttm_backend *radeon_ms_create_ttm_backend(struct drm_device * dev);
++uint64_t radeon_ms_evict_flags(struct drm_buffer_object *bo);
 +int radeon_ms_init_mem_type(struct drm_device * dev, uint32_t type,
 +                          struct drm_mem_type_manager * man);
 +int radeon_ms_invalidate_caches(struct drm_device * dev, uint64_t flags);
 +void radeon_ms_ttm_flush(struct drm_ttm *ttm);
 +
 +/* radeon_ms_bus.c */
 +int radeon_ms_agp_finish(struct drm_device *dev);
 +int radeon_ms_agp_init(struct drm_device *dev);
 +void radeon_ms_agp_restore(struct drm_device *dev, struct radeon_state *state);
 +void radeon_ms_agp_save(struct drm_device *dev, struct radeon_state *state);
 +struct drm_ttm_backend *radeon_ms_pcie_create_ttm(struct drm_device *dev);
 +int radeon_ms_pcie_finish(struct drm_device *dev);
 +int radeon_ms_pcie_init(struct drm_device *dev);
 +void radeon_ms_pcie_restore(struct drm_device *dev, struct radeon_state *state);
 +void radeon_ms_pcie_save(struct drm_device *dev, struct radeon_state *state);
 +
 +/* radeon_ms_combios.c */
 +int radeon_ms_combios_get_properties(struct drm_device *dev);
 +int radeon_ms_connectors_from_combios(struct drm_device *dev);
 +int radeon_ms_outputs_from_combios(struct drm_device *dev);
 +
 +/* radeon_ms_compat.c */
 +long radeon_ms_compat_ioctl(struct file *filp, unsigned int cmd,
 +                          unsigned long arg);
 +
 +/* radeon_ms_cp.c */
 +int radeon_ms_cp_finish(struct drm_device *dev);
 +int radeon_ms_cp_init(struct drm_device *dev);
 +void radeon_ms_cp_restore(struct drm_device *dev, struct radeon_state *state);
 +void radeon_ms_cp_save(struct drm_device *dev, struct radeon_state *state);
 +void radeon_ms_cp_stop(struct drm_device *dev);
 +int radeon_ms_cp_wait(struct drm_device *dev, int n);
 +int radeon_ms_ring_emit(struct drm_device *dev, uint32_t *cmd, uint32_t count);
 +
 +/* radeon_ms_crtc.c */
 +int radeon_ms_crtc_create(struct drm_device *dev, int crtc);
 +void radeon_ms_crtc1_restore(struct drm_device *dev,
 +                           struct radeon_state *state);
 +void radeon_ms_crtc1_save(struct drm_device *dev, struct radeon_state *state);
 +
 +/* radeon_ms_dac.c */
 +int radeon_ms_dac1_initialize(struct radeon_ms_output *output);
 +enum drm_output_status radeon_ms_dac1_detect(struct radeon_ms_output *output);
 +void radeon_ms_dac1_dpms(struct radeon_ms_output *output, int mode);
 +int radeon_ms_dac1_get_modes(struct radeon_ms_output *output);
 +bool radeon_ms_dac1_mode_fixup(struct radeon_ms_output *output,
 +              struct drm_display_mode *mode,
 +              struct drm_display_mode *adjusted_mode);
 +int radeon_ms_dac1_mode_set(struct radeon_ms_output *output,
 +              struct drm_display_mode *mode,
 +              struct drm_display_mode *adjusted_mode);
 +void radeon_ms_dac1_restore(struct radeon_ms_output *output,
 +              struct radeon_state *state);
 +void radeon_ms_dac1_save(struct radeon_ms_output *output,
 +              struct radeon_state *state);
 +int radeon_ms_dac2_initialize(struct radeon_ms_output *output);
 +enum drm_output_status radeon_ms_dac2_detect(struct radeon_ms_output *output);
 +void radeon_ms_dac2_dpms(struct radeon_ms_output *output, int mode);
 +int radeon_ms_dac2_get_modes(struct radeon_ms_output *output);
 +bool radeon_ms_dac2_mode_fixup(struct radeon_ms_output *output,
 +              struct drm_display_mode *mode,
 +              struct drm_display_mode *adjusted_mode);
 +int radeon_ms_dac2_mode_set(struct radeon_ms_output *output,
 +              struct drm_display_mode *mode,
 +              struct drm_display_mode *adjusted_mode);
 +void radeon_ms_dac2_restore(struct radeon_ms_output *output,
 +              struct radeon_state *state);
 +void radeon_ms_dac2_save(struct radeon_ms_output *output,
 +              struct radeon_state *state);
 +
 +/* radeon_ms_drm.c */
 +int radeon_ms_driver_dma_ioctl(struct drm_device *dev, void *data,
 +                             struct drm_file *file_priv);
 +void radeon_ms_driver_lastclose(struct drm_device * dev);
 +int radeon_ms_driver_load(struct drm_device *dev, unsigned long flags);
 +int radeon_ms_driver_open(struct drm_device * dev, struct drm_file *file_priv);
 +int radeon_ms_driver_unload(struct drm_device *dev);
 +
 +/* radeon_ms_exec.c */
 +int radeon_ms_execbuffer(struct drm_device *dev, void *data,
 +                       struct drm_file *file_priv);
 +
 +/* radeon_ms_family.c */
 +int radeon_ms_family_init(struct drm_device *dev);
 +
 +/* radeon_ms_fence.c */
 +int radeon_ms_fence_emit_sequence(struct drm_device *dev, uint32_t class,
 +                                uint32_t flags, uint32_t *sequence,
 +                                uint32_t *native_type);
 +void radeon_ms_fence_handler(struct drm_device * dev);
 +int radeon_ms_fence_has_irq(struct drm_device *dev, uint32_t class,
 +                          uint32_t flags);
 +int radeon_ms_fence_types(struct drm_buffer_object *bo,
 +                        uint32_t * class, uint32_t * type);
 +void radeon_ms_poke_flush(struct drm_device * dev, uint32_t class);
 +
 +/* radeon_ms_fb.c */
 +int radeonfb_probe(struct drm_device *dev, struct drm_crtc *crtc);
 +int radeonfb_remove(struct drm_device *dev, struct drm_crtc *crtc);
 +
 +/* radeon_ms_gpu.c */
 +int radeon_ms_gpu_initialize(struct drm_device *dev);
 +void radeon_ms_gpu_dpms(struct drm_device *dev);
 +void radeon_ms_gpu_flush(struct drm_device *dev);
 +void radeon_ms_gpu_restore(struct drm_device *dev, struct radeon_state *state);
 +void radeon_ms_gpu_save(struct drm_device *dev, struct radeon_state *state);
 +int radeon_ms_wait_for_idle(struct drm_device *dev);
 +
 +/* radeon_ms_i2c.c */
 +void radeon_ms_i2c_destroy(struct radeon_ms_i2c *i2c);
 +struct radeon_ms_i2c *radeon_ms_i2c_create(struct drm_device *dev,
 +                                         const uint32_t reg,
 +                                         const char *name);
 +
 +/* radeon_ms_irq.c */
 +void radeon_ms_irq_emit(struct drm_device *dev);
 +irqreturn_t radeon_ms_irq_handler(DRM_IRQ_ARGS);
 +void radeon_ms_irq_preinstall(struct drm_device * dev);
 +void radeon_ms_irq_postinstall(struct drm_device * dev);
 +int radeon_ms_irq_init(struct drm_device *dev);
 +void radeon_ms_irq_restore(struct drm_device *dev, struct radeon_state *state);
 +void radeon_ms_irq_save(struct drm_device *dev, struct radeon_state *state);
 +void radeon_ms_irq_uninstall(struct drm_device * dev);
 +
 +/* radeon_ms_output.c */
 +void radeon_ms_connectors_destroy(struct drm_device *dev);
 +int radeon_ms_connectors_from_properties(struct drm_device *dev);
 +int radeon_ms_connectors_from_rom(struct drm_device *dev);
 +void radeon_ms_outputs_destroy(struct drm_device *dev);
 +int radeon_ms_outputs_from_properties(struct drm_device *dev);
 +int radeon_ms_outputs_from_rom(struct drm_device *dev);
 +void radeon_ms_outputs_restore(struct drm_device *dev,
 +              struct radeon_state *state);
 +void radeon_ms_outputs_save(struct drm_device *dev, struct radeon_state *state);
 +
 +/* radeon_ms_properties.c */
 +int radeon_ms_properties_init(struct drm_device *dev);
 +
 +/* radeon_ms_rom.c */
 +int radeon_ms_rom_get_properties(struct drm_device *dev);
 +int radeon_ms_rom_init(struct drm_device *dev);
 +
 +/* radeon_ms_state.c */
 +void radeon_ms_state_save(struct drm_device *dev, struct radeon_state *state);
 +void radeon_ms_state_restore(struct drm_device *dev,
 +                           struct radeon_state *state);
 +
 +
 +/* packect stuff **************************************************************/
 +#define RADEON_CP_PACKET0                               0x00000000
 +#define CP_PACKET0(reg, n)                                            \
 +      (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
 +#define CP_PACKET3_CNTL_BITBLT_MULTI                    0xC0009B00
 +#    define GMC_SRC_PITCH_OFFSET_CNTL                       (1    <<  0)
 +#    define GMC_DST_PITCH_OFFSET_CNTL                       (1    <<  1)
 +#    define GMC_BRUSH_NONE                                  (15   <<  4)
 +#    define GMC_SRC_DATATYPE_COLOR                          (3    << 12)
 +#    define ROP3_S                                          0x00cc0000
 +#    define DP_SRC_SOURCE_MEMORY                            (2    << 24)
 +#    define GMC_CLR_CMP_CNTL_DIS                            (1    << 28)
 +#    define GMC_WR_MSK_DIS                                  (1    << 30)
 +
 +/* helper macro & functions ***************************************************/
 +#define REG_S(rn, bn, v)    (((v) << rn##__##bn##__SHIFT) & rn##__##bn##__MASK)
 +#define REG_G(rn, bn, v)    (((v) & rn##__##bn##__MASK) >> rn##__##bn##__SHIFT)
 +#define MMIO_R(rid)         mmio_read(dev_priv, rid)
 +#define MMIO_W(rid, v)      mmio_write(dev_priv, rid, v)
 +#define PCIE_R(rid)         pcie_read(dev_priv, rid)
 +#define PCIE_W(rid, v)      pcie_write(dev_priv, rid, v)
 +#define PPLL_R(rid)         pll_read(dev_priv, rid)
 +#define PPLL_W(rid, v)      pll_write(dev_priv, rid, v)
 +
 +static __inline__ uint32_t mmio_read(struct drm_radeon_private *dev_priv,
 +                                   uint32_t offset)
 +{
 +      return DRM_READ32(&dev_priv->mmio, offset);
 +}
 +
 +
 +static __inline__ void mmio_write(struct drm_radeon_private *dev_priv,
 +                                uint32_t offset, uint32_t v)
 +{
 +      DRM_WRITE32(&dev_priv->mmio, offset, v);
 +}
 +
 +static __inline__ uint32_t pcie_read(struct drm_radeon_private *dev_priv,
 +                                   uint32_t offset)
 +{
 +      MMIO_W(PCIE_INDEX, REG_S(PCIE_INDEX, PCIE_INDEX, offset));
 +      return MMIO_R(PCIE_DATA);
 +}
 +
 +static __inline__ void pcie_write(struct drm_radeon_private *dev_priv,
 +                                uint32_t offset, uint32_t v)
 +{
 +      MMIO_W(PCIE_INDEX, REG_S(PCIE_INDEX, PCIE_INDEX, offset));
 +      MMIO_W(PCIE_DATA, v);
 +}
 +
 +static __inline__ void pll_index_errata(struct drm_radeon_private *dev_priv)
 +{
 +      uint32_t tmp, save;
 +
 +      /* This workaround is necessary on rv200 and RS200 or PLL
 +       * reads may return garbage (among others...)
 +       */
 +      if (dev_priv->properties.pll_dummy_reads) {
 +              tmp = MMIO_R(CLOCK_CNTL_DATA);
 +              tmp = MMIO_R(CRTC_GEN_CNTL);
 +      }
 +      /* This function is required to workaround a hardware bug in some (all?)
 +       * revisions of the R300.  This workaround should be called after every
 +       * CLOCK_CNTL_INDEX register access.  If not, register reads afterward
 +       * may not be correct.
 +       */
 +      if (dev_priv->properties.pll_r300_errata) {
 +              tmp = save = MMIO_R(CLOCK_CNTL_INDEX);
 +              tmp = tmp & ~CLOCK_CNTL_INDEX__PLL_ADDR__MASK;
 +              tmp = tmp & ~CLOCK_CNTL_INDEX__PLL_WR_EN;
 +              MMIO_W(CLOCK_CNTL_INDEX, tmp);
 +              tmp = MMIO_R(CLOCK_CNTL_DATA);
 +              MMIO_W(CLOCK_CNTL_INDEX, save);
 +      }
 +}
 +
 +static __inline__ void pll_data_errata(struct drm_radeon_private *dev_priv)
 +{
 +      /* This workarounds is necessary on RV100, RS100 and RS200 chips
 +       * or the chip could hang on a subsequent access
 +       */
 +      if (dev_priv->properties.pll_delay) {
 +              /* we can't deal with posted writes here ... */
 +              udelay(5000);
 +      }
 +}
 +
 +static __inline__ uint32_t pll_read(struct drm_radeon_private *dev_priv,
 +                                  uint32_t offset)
 +{
 +      uint32_t clock_cntl_index = dev_priv->driver_state.clock_cntl_index;
 +      uint32_t data;
 +
 +      clock_cntl_index &= ~CLOCK_CNTL_INDEX__PLL_ADDR__MASK;
 +      clock_cntl_index |= REG_S(CLOCK_CNTL_INDEX, PLL_ADDR, offset);
 +      MMIO_W(CLOCK_CNTL_INDEX, clock_cntl_index);
 +      pll_index_errata(dev_priv);
 +      data = MMIO_R(CLOCK_CNTL_DATA);
 +      pll_data_errata(dev_priv);
 +      return data;
 +}
 +
 +static __inline__ void pll_write(struct drm_radeon_private *dev_priv,
 +                               uint32_t offset, uint32_t value)
 +{
 +      uint32_t clock_cntl_index = dev_priv->driver_state.clock_cntl_index;
 +
 +      clock_cntl_index &= ~CLOCK_CNTL_INDEX__PLL_ADDR__MASK;
 +      clock_cntl_index |= REG_S(CLOCK_CNTL_INDEX, PLL_ADDR, offset);
 +      clock_cntl_index |= CLOCK_CNTL_INDEX__PLL_WR_EN;
 +      MMIO_W(CLOCK_CNTL_INDEX, clock_cntl_index);
 +      pll_index_errata(dev_priv);
 +      MMIO_W(CLOCK_CNTL_DATA, value);
 +      pll_data_errata(dev_priv);
 +}
 +
 +#endif
index cedad68,0000000..6d9a97c
mode 100644,000000..100644
--- /dev/null
@@@ -1,311 -1,0 +1,311 @@@
-       tmp_mem.mask = DRM_BO_FLAG_MEM_TT |
 +/*
 + * Copyright 2007 Dave Airlie
 + * Copyright 2007 Jérôme Glisse
 + * All Rights Reserved.
 + * 
 + * Permission is hereby granted, free of charge, to any person obtaining a
 + * copy of this software and associated documentation files (the
 + * "Software"), to deal in the Software without restriction, including
 + * without limitation the rights to use, copy, modify, merge, publish,
 + * distribute, sub license, and/or sell copies of the Software, and to
 + * permit persons to whom the Software is furnished to do so, subject to
 + * the following conditions:
 + * 
 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
 + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
 + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 
 + * USE OR OTHER DEALINGS IN THE SOFTWARE.
 + *
 + * The above copyright notice and this permission notice (including the
 + * next paragraph) shall be included in all copies or substantial portions
 + * of the Software.
 + */
 +/*
 + * Authors:
 + *    Dave Airlie <airlied@linux.ie>
 + *    Jerome Glisse <glisse@freedesktop.org>
 + */
 +#include "drmP.h"
 +#include "drm.h"
 +
 +#include "radeon_ms.h"
 +
 +void radeon_ms_bo_copy_blit(struct drm_device *dev,
 +                          uint32_t src_offset,
 +                          uint32_t dst_offset,
 +                          uint32_t pages)
 +{
 +      struct drm_radeon_private *dev_priv = dev->dev_private;
 +      uint32_t num_pages, stride, c;
 +      uint32_t offset_inc = 0;
 +      uint32_t cmd[7];
 +
 +      if (!dev_priv) {
 +              return;
 +      }
 +
 +      /* radeon limited to 16320=255*64 bytes per row so copy at
 +       * most 2 pages */
 +      num_pages = 2;
 +      stride = ((num_pages * PAGE_SIZE) / 64) & 0xff;
 +      while(pages > 0) {
 +              if (num_pages > pages) {
 +                      num_pages = pages;
 +                      stride = ((num_pages * PAGE_SIZE) / 64) & 0xff;
 +              }
 +              c = pages / num_pages;
 +              if (c >= 8192) {
 +                      c = 8191;
 +              }
 +              cmd[0] = CP_PACKET3_CNTL_BITBLT_MULTI | (5 << 16);
 +              cmd[1] = GMC_SRC_PITCH_OFFSET_CNTL |
 +                       GMC_DST_PITCH_OFFSET_CNTL |
 +                       GMC_BRUSH_NONE |
 +                       (0x6 << 8) |
 +                       GMC_SRC_DATATYPE_COLOR |
 +                       ROP3_S |
 +                       DP_SRC_SOURCE_MEMORY |
 +                       GMC_CLR_CMP_CNTL_DIS |
 +                       GMC_WR_MSK_DIS;
 +              cmd[2] = (stride << 22) | (src_offset >> 10);
 +              cmd[3] = (stride << 22) | (dst_offset >> 10);
 +              cmd[4] = (0 << 16) | 0;
 +              cmd[5] = (0 << 16) | 0;
 +              cmd[6] = ((stride * 16) << 16) | c;
 +              radeon_ms_ring_emit(dev, cmd, 7);
 +              offset_inc = num_pages * c * PAGE_SIZE;
 +              src_offset += offset_inc;
 +              dst_offset += offset_inc;
 +              pages -= num_pages * c;
 +      }
 +      /* wait for 2d engine to go busy so wait_until stall */
 +      for (c = 0; c < dev_priv->usec_timeout; c++) {
 +              uint32_t status = MMIO_R(RBBM_STATUS);
 +              if ((RBBM_STATUS__E2_BUSY & status) ||
 +                  (RBBM_STATUS__CBA2D_BUSY & status)) {
 +                      DRM_INFO("[radeon_ms] RBBM_STATUS 0x%08X\n", status);
 +                      break;
 +              }
 +              DRM_UDELAY(1);
 +      }
 +      /* Sync everything up */
 +      cmd[0] = CP_PACKET0(WAIT_UNTIL, 0);
 +      cmd[1] = WAIT_UNTIL__WAIT_2D_IDLECLEAN |
 +               WAIT_UNTIL__WAIT_HOST_IDLECLEAN;
 +      radeon_ms_ring_emit(dev, cmd, 2);
 +      return;
 +}
 +
 +static int radeon_ms_bo_move_blit(struct drm_buffer_object *bo,
 +                                int evict, int no_wait,
 +                                struct drm_bo_mem_reg *new_mem)
 +{
 +      struct drm_device *dev = bo->dev;
 +      struct drm_bo_mem_reg *old_mem = &bo->mem;
 +      uint32_t gpu_src_addr;
 +      uint32_t gpu_dst_addr;
 +      int ret;
 +
 +      ret = radeon_ms_bo_get_gpu_addr(dev, old_mem, &gpu_src_addr);
 +      if (ret) {
 +              return ret;
 +      }
 +      ret = radeon_ms_bo_get_gpu_addr(dev, new_mem, &gpu_dst_addr);
 +      if (ret) {
 +              return ret;
 +      }
 +
 +      radeon_ms_bo_copy_blit(bo->dev,
 +                             gpu_src_addr,
 +                             gpu_dst_addr,
 +                             new_mem->num_pages);
 +      
 +      ret = drm_bo_move_accel_cleanup(bo, evict, no_wait, 0,
 +                                       DRM_FENCE_TYPE_EXE |
 +                                       DRM_RADEON_FENCE_TYPE_RW,
 +                                       DRM_RADEON_FENCE_FLAG_FLUSHED,
 +                                       new_mem);
 +      return ret;
 +}
 +
 +static int radeon_ms_bo_move_flip(struct drm_buffer_object *bo,
 +                                int evict, int no_wait,
 +                                struct drm_bo_mem_reg *new_mem)
 +{
 +      struct drm_device *dev = bo->dev;
 +      struct drm_bo_mem_reg tmp_mem;
 +      int ret;
 +
 +      tmp_mem = *new_mem;
 +      tmp_mem.mm_node = NULL;
-       ret = drm_bind_ttm(bo->ttm, &tmp_mem);
++      tmp_mem.flags = DRM_BO_FLAG_MEM_TT |
 +                     DRM_BO_FLAG_CACHED |
 +                     DRM_BO_FLAG_FORCE_CACHING;
 +      ret = drm_bo_mem_space(bo, &tmp_mem, no_wait);
 +      if (ret) {
 +              return ret;
 +      }
 +
- uint32_t radeon_ms_evict_mask(struct drm_buffer_object *bo)
++      ret = drm_ttm_bind(bo->ttm, &tmp_mem);
 +      if (ret) {
 +              goto out_cleanup;
 +      }
 +      ret = radeon_ms_bo_move_blit(bo, 1, no_wait, &tmp_mem);
 +      if (ret) {
 +              goto out_cleanup;
 +      }
 +      ret = drm_bo_move_ttm(bo, evict, no_wait, new_mem);
 +out_cleanup:
 +      if (tmp_mem.mm_node) {
 +              mutex_lock(&dev->struct_mutex);
 +              if (tmp_mem.mm_node != bo->pinned_node)
 +                      drm_mm_put_block(tmp_mem.mm_node);
 +              tmp_mem.mm_node = NULL;
 +              mutex_unlock(&dev->struct_mutex);
 +      }
 +      return ret;
 +}
 +
 +int radeon_ms_bo_get_gpu_addr(struct drm_device *dev,
 +                            struct drm_bo_mem_reg *mem,
 +                            uint32_t *gpu_addr)
 +{
 +      struct drm_radeon_private *dev_priv = dev->dev_private;
 +
 +      *gpu_addr = mem->mm_node->start << PAGE_SHIFT;
 +      switch (mem->flags & DRM_BO_MASK_MEM) {
 +      case DRM_BO_FLAG_MEM_TT:
 +              *gpu_addr +=  dev_priv->gpu_gart_start;
 +              DRM_INFO("[radeon_ms] GPU TT: 0x%08X\n", *gpu_addr);
 +              break;
 +      case DRM_BO_FLAG_MEM_VRAM:
 +              *gpu_addr +=  dev_priv->gpu_vram_start;
 +              DRM_INFO("[radeon_ms] GPU VRAM: 0x%08X\n", *gpu_addr);
 +              break;
 +      default:
 +              DRM_ERROR("[radeon_ms] memory not accessible by GPU\n");
 +              return -EINVAL;
 +      }
 +      return 0;
 +}
 +
 +int radeon_ms_bo_move(struct drm_buffer_object *bo, int evict,
 +                 int no_wait, struct drm_bo_mem_reg *new_mem)
 +{
 +      struct drm_bo_mem_reg *old_mem = &bo->mem;
 +      if (old_mem->mem_type == DRM_BO_MEM_LOCAL) {
 +              return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
 +      } else if (new_mem->mem_type == DRM_BO_MEM_LOCAL) {
 +              if (radeon_ms_bo_move_flip(bo, evict, no_wait, new_mem))
 +                      return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
 +      } else {
 +              if (radeon_ms_bo_move_blit(bo, evict, no_wait, new_mem))
 +                      return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
 +      }
 +      return 0;
 +}
 +
 +struct drm_ttm_backend *radeon_ms_create_ttm_backend(struct drm_device * dev)
 +{
 +      struct drm_radeon_private *dev_priv = dev->dev_private;
 +
 +      if (dev_priv && dev_priv->create_ttm)
 +              return dev_priv->create_ttm(dev);
 +      return NULL;
 +}
 +
++uint64_t radeon_ms_evict_flags(struct drm_buffer_object *bo)
 +{
 +      switch (bo->mem.mem_type) {
 +      case DRM_BO_MEM_LOCAL:
 +      case DRM_BO_MEM_TT:
 +              return DRM_BO_FLAG_MEM_LOCAL;
 +      case DRM_BO_MEM_VRAM:
 +              if (bo->mem.num_pages > 128)
 +                      return DRM_BO_MEM_TT;
 +              else
 +                      return DRM_BO_MEM_LOCAL;
 +      default:
 +              return DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_CACHED;
 +      }
 +}
 +
 +int radeon_ms_init_mem_type(struct drm_device * dev, uint32_t type,
 +                          struct drm_mem_type_manager * man)
 +{
 +      struct drm_radeon_private *dev_priv = dev->dev_private;
 +
 +      switch (type) {
 +      case DRM_BO_MEM_LOCAL:
 +              man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
 +                  _DRM_FLAG_MEMTYPE_CACHED;
 +              man->drm_bus_maptype = 0;
 +              break;
 +      case DRM_BO_MEM_VRAM:
 +              man->flags =  _DRM_FLAG_MEMTYPE_FIXED |
 +                            _DRM_FLAG_MEMTYPE_MAPPABLE |
 +                            _DRM_FLAG_NEEDS_IOREMAP;
 +              man->io_addr = NULL;
 +              man->drm_bus_maptype = _DRM_FRAME_BUFFER;
 +              man->io_offset = dev_priv->vram.offset;
 +              man->io_size = dev_priv->vram.size;
 +              break;
 +      case DRM_BO_MEM_TT:
 +              if (!dev_priv->bus_ready) {
 +                      DRM_ERROR("Bus isn't initialized while "
 +                                "intializing TT memory type\n");
 +                      return -EINVAL;
 +              }
 +              switch(dev_priv->bus_type) {
 +              case RADEON_AGP:
 +                      if (!(drm_core_has_AGP(dev) && dev->agp)) {
 +                              DRM_ERROR("AGP is not enabled for memory "
 +                                        "type %u\n", (unsigned)type);
 +                              return -EINVAL;
 +                      }
 +                      man->io_offset = dev->agp->agp_info.aper_base;
 +                      man->io_size = dev->agp->agp_info.aper_size *
 +                                     1024 * 1024;
 +                      man->io_addr = NULL;
 +                      man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
 +                                   _DRM_FLAG_MEMTYPE_CSELECT |
 +                                   _DRM_FLAG_NEEDS_IOREMAP;
 +                      man->drm_bus_maptype = _DRM_AGP;
 +                      man->gpu_offset = 0;
 +                      break;
 +              default:
 +                      man->io_offset = dev_priv->gpu_gart_start;
 +                      man->io_size = dev_priv->gpu_gart_size;
 +                      man->io_addr = NULL;
 +                      man->flags = _DRM_FLAG_MEMTYPE_CSELECT |
 +                                   _DRM_FLAG_MEMTYPE_MAPPABLE |
 +                                   _DRM_FLAG_MEMTYPE_CMA;
 +                      man->drm_bus_maptype = _DRM_SCATTER_GATHER;
 +                      break;
 +              }
 +              break;
 +      default:
 +              DRM_ERROR("Unsupported memory type %u\n", (unsigned)type);
 +              return -EINVAL;
 +      }
 +      return 0;
 +}
 +
 +int radeon_ms_invalidate_caches(struct drm_device * dev, uint64_t flags)
 +{
 +      struct drm_radeon_private *dev_priv = dev->dev_private;
 +
 +      dev_priv->flush_cache(dev);
 +      return 0;
 +}
 +
 +void radeon_ms_ttm_flush(struct drm_ttm *ttm)
 +{
 +      if (!ttm)
 +              return;
 +
 +      DRM_MEMORYBARRIER();
 +}
index 91ca4a3,0000000..bf76b45
mode 100644,000000..100644
--- /dev/null
@@@ -1,318 -1,0 +1,318 @@@
-       .evict_mask = radeon_ms_evict_mask,
 +/*
 + * Copyright 2007 Jérôme Glisse
 + * Copyright 2007 Alex Deucher
 + * Copyright 2007 Dave Airlie
 + * All Rights Reserved.
 + *
 + * Permission is hereby granted, free of charge, to any person obtaining a
 + * copy of this software and associated documentation files (the "Software"),
 + * to deal in the Software without restriction, including without limitation
 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 + * and/or sell copies of the Software, and to permit persons to whom the
 + * Software is furnished to do so, subject to the following conditions:
 + *
 + * The above copyright notice and this permission notice (including the next
 + * paragraph) shall be included in all copies or substantial portions of the
 + * Software.
 + *
 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 + * DEALINGS IN THE SOFTWARE.
 + */
 +/*
 + * Authors:
 + *    Jerome Glisse <glisse@freedesktop.org>
 + */
 +#include "drm_pciids.h"
 +#include "radeon_ms.h"
 +
 +
 +static uint32_t radeon_ms_mem_prios[] = {
 +      DRM_BO_MEM_VRAM,
 +      DRM_BO_MEM_TT,
 +      DRM_BO_MEM_LOCAL,
 +};
 +
 +static uint32_t radeon_ms_busy_prios[] = {
 +      DRM_BO_MEM_TT,
 +      DRM_BO_MEM_VRAM,
 +      DRM_BO_MEM_LOCAL,
 +};
 +
 +struct drm_fence_driver radeon_ms_fence_driver = {
 +      .num_classes = 1,
 +      .wrap_diff = (1 << 30),
 +      .flush_diff = (1 << 29),
 +      .sequence_mask = 0xffffffffU,
 +      .lazy_capable = 1,
 +      .emit = radeon_ms_fence_emit_sequence,
 +      .poke_flush = radeon_ms_poke_flush,
 +      .has_irq = radeon_ms_fence_has_irq,
 +};
 +
 +struct drm_bo_driver radeon_ms_bo_driver = {
 +      .mem_type_prio = radeon_ms_mem_prios,
 +      .mem_busy_prio = radeon_ms_busy_prios,
 +      .num_mem_type_prio = sizeof(radeon_ms_mem_prios)/sizeof(uint32_t),
 +      .num_mem_busy_prio = sizeof(radeon_ms_busy_prios)/sizeof(uint32_t),
 +      .create_ttm_backend_entry = radeon_ms_create_ttm_backend,
 +      .fence_type = radeon_ms_fence_types,
 +      .invalidate_caches = radeon_ms_invalidate_caches,
 +      .init_mem_type = radeon_ms_init_mem_type,
++      .evict_flags = radeon_ms_evict_flags,
 +      .move = radeon_ms_bo_move,
 +      .ttm_cache_flush = radeon_ms_ttm_flush,
 +};
 +
 +struct drm_ioctl_desc radeon_ms_ioctls[] = {
 +      DRM_IOCTL_DEF(DRM_RADEON_EXECBUFFER, radeon_ms_execbuffer, DRM_AUTH),
 +};
 +int radeon_ms_num_ioctls = DRM_ARRAY_SIZE(radeon_ms_ioctls);
 +
 +int radeon_ms_driver_dma_ioctl(struct drm_device *dev, void *data,
 +                             struct drm_file *file_priv)
 +{
 +      struct drm_device_dma *dma = dev->dma;
 +      struct drm_dma *d = data;
 +
 +      LOCK_TEST_WITH_RETURN(dev, file_priv);
 +
 +      /* Please don't send us buffers.
 +       */
 +      if (d->send_count != 0) {
 +              DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
 +                        DRM_CURRENTPID, d->send_count);
 +              return -EINVAL;
 +      }
 +
 +      /* Don't ask us buffer neither :)
 +       */
 +      DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
 +                DRM_CURRENTPID, d->request_count, dma->buf_count);
 +      return -EINVAL;
 +}
 +
 +void radeon_ms_driver_lastclose(struct drm_device * dev)
 +{
 +}
 +
 +int radeon_ms_driver_load(struct drm_device *dev, unsigned long flags)
 +{
 +      struct drm_radeon_private *dev_priv;
 +      int ret = 0;
 +
 +      DRM_INFO("[radeon_ms] loading\n");
 +      /* allocate and clear device private structure */
 +      dev_priv = drm_alloc(sizeof(struct drm_radeon_private), DRM_MEM_DRIVER);
 +      if (dev_priv == NULL)
 +              return -ENOMEM;
 +      memset(dev_priv, 0, sizeof(struct drm_radeon_private));
 +      dev->dev_private = (void *)dev_priv;
 +
 +      /* initialize modesetting structure (must be done here) */
 +      drm_mode_config_init(dev);
 +
 +      /* flags correspond to chipset family */
 +      dev_priv->usec_timeout = 100;
 +      dev_priv->family = flags & 0xffffU;
 +      dev_priv->bus_type = flags & 0xff0000U;
 +      /* initialize family functions */
 +      ret = radeon_ms_family_init(dev);
 +      if (ret != 0) {
 +              radeon_ms_driver_unload(dev);
 +              return ret;
 +      }
 +
 +      /* we don't want userspace to be able to map this so don't use
 +       * drm_addmap */
 +      dev_priv->mmio.offset = drm_get_resource_start(dev, 2);
 +      dev_priv->mmio.size = drm_get_resource_len(dev, 2);
 +      dev_priv->mmio.type = _DRM_REGISTERS;
 +      dev_priv->mmio.flags = _DRM_RESTRICTED;
 +      drm_core_ioremap(&dev_priv->mmio, dev); 
 +      /* map vram FIXME: IGP likely don't have any of this */
 +      dev_priv->vram.offset = drm_get_resource_start(dev, 0);
 +      dev_priv->vram.size = drm_get_resource_len(dev, 0);
 +      dev_priv->vram.type = _DRM_FRAME_BUFFER;
 +      dev_priv->vram.flags = _DRM_RESTRICTED;
 +      drm_core_ioremap(&dev_priv->vram, dev);
 +
 +      /* save radeon initial state which will be restored upon module
 +       * exit */
 +      radeon_ms_state_save(dev, &dev_priv->load_state);
 +      dev_priv->restore_state = 1;
 +      memcpy(&dev_priv->driver_state, &dev_priv->load_state,
 +             sizeof(struct radeon_state));
 +
 +      /* initialize irq */
 +      ret = radeon_ms_irq_init(dev);
 +      if (ret != 0) {
 +              radeon_ms_driver_unload(dev);
 +              return ret;
 +      }
 +
 +      /* init bo driver */
 +      dev_priv->fence_id_last = 1;
 +      dev_priv->fence_reg = SCRATCH_REG2;
 +      drm_bo_driver_init(dev);
 +      /* initialize vram */
 +      ret = drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, dev_priv->vram.size);
 +      if (ret != 0) {
 +              radeon_ms_driver_unload(dev);
 +              return ret;
 +      }
 +
 +      /* initialize gpu address space (only after) VRAM initialization */
 +      ret = radeon_ms_gpu_initialize(dev);
 +      if (ret != 0) {
 +              radeon_ms_driver_unload(dev);
 +              return ret;
 +      }
 +      radeon_ms_gpu_restore(dev, &dev_priv->driver_state);
 +
 +      /* initialize ttm */
 +      ret = drm_bo_init_mm(dev, DRM_BO_MEM_TT, 0,
 +                           dev_priv->gpu_gart_size / RADEON_PAGE_SIZE);
 +      if (ret != 0) {
 +              radeon_ms_driver_unload(dev);
 +              return ret;
 +      }
 +
 +      /* initialize ring buffer */
 +      /* set ring size to 4Mo FIXME: should make a parameter for this */
 +      dev_priv->write_back_area_size = 4 * 1024;
 +      dev_priv->ring_buffer_size = 4 * 1024 * 1024;
 +      ret = radeon_ms_cp_init(dev);
 +      if (ret != 0) {
 +              radeon_ms_driver_unload(dev);
 +              return ret;
 +      }
 +
 +      /* initialize modesetting */
 +      dev->mode_config.min_width = 0;
 +      dev->mode_config.min_height = 0;
 +      dev->mode_config.max_width = 4096;
 +      dev->mode_config.max_height = 4096;
 +      dev->mode_config.fb_base = dev_priv->vram.offset;
 +      ret = radeon_ms_crtc_create(dev, 1);
 +      if (ret != 0) {
 +              radeon_ms_driver_unload(dev);
 +              return ret;
 +      }
 +      ret = radeon_ms_outputs_from_rom(dev);
 +      if (ret < 0) {
 +              radeon_ms_driver_unload(dev);
 +              return ret;
 +      } else if (!ret) {
 +              ret = radeon_ms_outputs_from_properties(dev);
 +              if (ret < 0) {
 +                      radeon_ms_driver_unload(dev);
 +                      return ret;
 +              } else if (ret == 0) {
 +                      DRM_INFO("[radeon_ms] no outputs !\n");
 +              }
 +      } else {
 +              DRM_INFO("[radeon_ms] added %d outputs from rom.\n", ret);
 +      }
 +      ret = radeon_ms_connectors_from_rom(dev);
 +      if (ret < 0) {
 +              radeon_ms_driver_unload(dev);
 +              return ret;
 +      } else if (!ret) {
 +              ret = radeon_ms_connectors_from_properties(dev);
 +              if (ret < 0) {
 +                      radeon_ms_driver_unload(dev);
 +                      return ret;
 +              } else if (!ret) {
 +                      DRM_INFO("[radeon_ms] no connectors !\n");
 +              }
 +      } else {
 +              DRM_INFO("[radeon_ms] added %d connectors from rom.\n", ret);
 +      }
 +      radeon_ms_outputs_save(dev, &dev_priv->load_state);
 +      drm_initial_config(dev, false);
 +
 +      ret = drm_irq_install(dev);
 +      if (ret != 0) {
 +              radeon_ms_driver_unload(dev);
 +              return ret;
 +      }
 +
 +      DRM_INFO("[radeon_ms] successfull initialization\n");
 +      return 0;
 +}
 +
 +int radeon_ms_driver_open(struct drm_device * dev, struct drm_file *file_priv)
 +{
 +      return 0;
 +}
 +
 +
 +int radeon_ms_driver_unload(struct drm_device *dev)
 +{
 +      struct drm_radeon_private *dev_priv = dev->dev_private;
 +
 +      if (dev_priv == NULL) {
 +              return 0;
 +      }
 +
 +      /* cleanup modesetting */
 +      drm_mode_config_cleanup(dev);
 +      DRM_INFO("[radeon_ms] modesetting clean\n");
 +      radeon_ms_outputs_restore(dev, &dev_priv->load_state);
 +      radeon_ms_connectors_destroy(dev);
 +      radeon_ms_outputs_destroy(dev);
 +      
 +      /* shutdown cp engine */
 +      radeon_ms_cp_finish(dev);
 +      DRM_INFO("[radeon_ms] cp clean\n");
 +
 +      drm_irq_uninstall(dev);
 +      DRM_INFO("[radeon_ms] irq uninstalled\n");
 +
 +      DRM_INFO("[radeon_ms] unloading\n");
 +      /* clean ttm memory manager */
 +      mutex_lock(&dev->struct_mutex);
 +      if (drm_bo_clean_mm(dev, DRM_BO_MEM_TT)) {
 +              DRM_ERROR("TT memory manager not clean. Delaying takedown\n");
 +      }
 +      mutex_unlock(&dev->struct_mutex);
 +      DRM_INFO("[radeon_ms] TT memory clean\n");
 +      /* finish */
 +      if (dev_priv->bus_finish) {
 +              dev_priv->bus_finish(dev);
 +      }
 +      DRM_INFO("[radeon_ms] bus down\n");
 +      /* clean vram memory manager */
 +      mutex_lock(&dev->struct_mutex);
 +      if (drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM)) {
 +              DRM_ERROR("VRAM memory manager not clean. Delaying takedown\n");
 +      }
 +      mutex_unlock(&dev->struct_mutex);
 +      DRM_INFO("[radeon_ms] VRAM memory clean\n");
 +      /* clean memory manager */
 +      drm_bo_driver_finish(dev);
 +      DRM_INFO("[radeon_ms] memory manager clean\n");
 +      /* restore card state */
 +      if (dev_priv->restore_state) {
 +              radeon_ms_state_restore(dev, &dev_priv->load_state);
 +      }
 +      DRM_INFO("[radeon_ms] state restored\n");
 +      if (dev_priv->mmio.handle) {
 +              drm_core_ioremapfree(&dev_priv->mmio, dev);
 +      }
 +      if (dev_priv->vram.handle) {
 +              drm_core_ioremapfree(&dev_priv->vram, dev);
 +      }
 +      DRM_INFO("[radeon_ms] map released\n");
 +      drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
 +      dev->dev_private = NULL;
 +
 +      DRM_INFO("[radeon_ms] that's all the folks\n");
 +      return 0;
 +}
 +