Re: [PATCH 07/12] drm/ttm: merge ttm_backend and ttm_tt

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 11/08/2011 12:40 AM, j.glisse@xxxxxxxxx wrote:
From: Jerome Glisse<jglisse@xxxxxxxxxx>

ttm_backend will exist only and only with a ttm_tt, and ttm_tt
will be of interesting use only when bind to a backend. Thus to
avoid code&  data duplication btw the two merge them.


Looks mainly good, but I'd still like to get rid of the
struct ttm_tt dma_address member, and likewise the upcoming alloc_list member. What about introducing the following struct that may be used by drivers that support dma pages:

struct ttm_dma_tt {
    struct ttm_tt ttm;
    ...dma stuff..
};

The bo code only cares about the ttm_tt struct, whereas the backends could back it with whatever they need. For example, the AGP backend could be returning a ttm_dma_tt if needed.

Also, I think we should take the opportunity to get rid of the dummy_read_page. It's pretty
backend specific?

/Thomas


Signed-off-by: Jerome Glisse<jglisse@xxxxxxxxxx>
Reviewed-by: Konrad Rzeszutek Wilk<konrad.wilk@xxxxxxxxxx>
---
  drivers/gpu/drm/nouveau/nouveau_bo.c    |   14 ++-
  drivers/gpu/drm/nouveau/nouveau_drv.h   |    5 +-
  drivers/gpu/drm/nouveau/nouveau_sgdma.c |  188 ++++++++++++--------------
  drivers/gpu/drm/radeon/radeon_ttm.c     |  222 ++++++++++++-------------------
  drivers/gpu/drm/ttm/ttm_agp_backend.c   |   88 +++++--------
  drivers/gpu/drm/ttm/ttm_bo.c            |    9 +-
  drivers/gpu/drm/ttm/ttm_tt.c            |   59 ++-------
  drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c  |   66 +++------
  include/drm/ttm/ttm_bo_driver.h         |  104 ++++++---------
  9 files changed, 295 insertions(+), 460 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 7226f41..b060fa4 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -343,8 +343,10 @@ nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val)
  		*mem = val;
  }

-static struct ttm_backend *
-nouveau_bo_create_ttm_backend_entry(struct ttm_bo_device *bdev)
+static struct ttm_tt *
+nouveau_ttm_tt_create(struct ttm_bo_device *bdev,
+		      unsigned long size, uint32_t page_flags,
+		      struct page *dummy_read_page)
  {
  	struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev);
  	struct drm_device *dev = dev_priv->dev;
@@ -352,11 +354,13 @@ nouveau_bo_create_ttm_backend_entry(struct ttm_bo_device *bdev)
  	switch (dev_priv->gart_info.type) {
  #if __OS_HAS_AGP
  	case NOUVEAU_GART_AGP:
-		return ttm_agp_backend_init(bdev, dev->agp->bridge);
+		return ttm_agp_tt_create(bdev, dev->agp->bridge,
+					 size, page_flags, dummy_read_page);
  #endif
  	case NOUVEAU_GART_PDMA:
  	case NOUVEAU_GART_HW:
-		return nouveau_sgdma_init_ttm(dev);
+		return nouveau_sgdma_create_ttm(bdev, size, page_flags,
+						dummy_read_page);
  	default:
  		NV_ERROR(dev, "Unknown GART type %d\n",
  			 dev_priv->gart_info.type);
@@ -1045,7 +1049,7 @@ nouveau_bo_fence(struct nouveau_bo *nvbo, struct nouveau_fence *fence)
  }

  struct ttm_bo_driver nouveau_bo_driver = {
-	.create_ttm_backend_entry = nouveau_bo_create_ttm_backend_entry,
+	.ttm_tt_create =&nouveau_ttm_tt_create,
  	.invalidate_caches = nouveau_bo_invalidate_caches,
  	.init_mem_type = nouveau_bo_init_mem_type,
  	.evict_flags = nouveau_bo_evict_flags,
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 29837da..0c53e39 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -1000,7 +1000,10 @@ extern int nouveau_sgdma_init(struct drm_device *);
  extern void nouveau_sgdma_takedown(struct drm_device *);
  extern uint32_t nouveau_sgdma_get_physical(struct drm_device *,
  					   uint32_t offset);
-extern struct ttm_backend *nouveau_sgdma_init_ttm(struct drm_device *);
+extern struct ttm_tt *nouveau_sgdma_create_ttm(struct ttm_bo_device *bdev,
+					       unsigned long size,
+					       uint32_t page_flags,
+					       struct page *dummy_read_page);

  /* nouveau_debugfs.c */
  #if defined(CONFIG_DRM_NOUVEAU_DEBUG)
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
index b75258a..bc2ab90 100644
--- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
@@ -8,44 +8,23 @@
  #define NV_CTXDMA_PAGE_MASK  (NV_CTXDMA_PAGE_SIZE - 1)

  struct nouveau_sgdma_be {
-	struct ttm_backend backend;
+	struct ttm_tt ttm;
  	struct drm_device *dev;
-
-	dma_addr_t *pages;
-	unsigned nr_pages;
-	bool unmap_pages;
-
  	u64 offset;
-	bool bound;
  };

  static int
-nouveau_sgdma_populate(struct ttm_backend *be, unsigned long num_pages,
-		       struct page **pages, struct page *dummy_read_page,
-		       dma_addr_t *dma_addrs)
+nouveau_sgdma_dma_map(struct ttm_tt *ttm)
  {
-	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
  	struct drm_device *dev = nvbe->dev;
  	int i;

-	NV_DEBUG(nvbe->dev, "num_pages = %ld\n", num_pages);
-
-	nvbe->pages = dma_addrs;
-	nvbe->nr_pages = num_pages;
-	nvbe->unmap_pages = true;
-
-	/* this code path isn't called and is incorrect anyways */
-	if (0) { /* dma_addrs[0] != DMA_ERROR_CODE) { */
-		nvbe->unmap_pages = false;
-		return 0;
-	}
-
-	for (i = 0; i<  num_pages; i++) {
-		nvbe->pages[i] = pci_map_page(dev->pdev, pages[i], 0,
-					      PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
-		if (pci_dma_mapping_error(dev->pdev, nvbe->pages[i])) {
-			nvbe->nr_pages = --i;
-			be->func->clear(be);
+	for (i = 0; i<  ttm->num_pages; i++) {
+		ttm->dma_address[i] = pci_map_page(dev->pdev, ttm->pages[i],
+						   0, PAGE_SIZE,
+						   PCI_DMA_BIDIRECTIONAL);
+		if (pci_dma_mapping_error(dev->pdev, ttm->dma_address[i])) {
  			return -EFAULT;
  		}
  	}
@@ -54,53 +33,52 @@ nouveau_sgdma_populate(struct ttm_backend *be, unsigned long num_pages,
  }

  static void
-nouveau_sgdma_clear(struct ttm_backend *be)
+nouveau_sgdma_dma_unmap(struct ttm_tt *ttm)
  {
-	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
  	struct drm_device *dev = nvbe->dev;
+	int i;

-	if (nvbe->bound)
-		be->func->unbind(be);
-
-	if (nvbe->unmap_pages) {
-		while (nvbe->nr_pages--) {
-			pci_unmap_page(dev->pdev, nvbe->pages[nvbe->nr_pages],
+	for (i = 0; i<  ttm->num_pages; i++) {
+		if (ttm->dma_address[i]) {
+			pci_unmap_page(dev->pdev, ttm->dma_address[i],
  				       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
  		}
+		ttm->dma_address[i] = 0;
  	}
  }

  static void
-nouveau_sgdma_destroy(struct ttm_backend *be)
+nouveau_sgdma_destroy(struct ttm_tt *ttm)
  {
-	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;

-	if (be) {
+	if (ttm) {
  		NV_DEBUG(nvbe->dev, "\n");
-
-		if (nvbe) {
-			if (nvbe->pages)
-				be->func->clear(be);
-			kfree(nvbe);
-		}
+		kfree(nvbe);
  	}
  }

  static int
-nv04_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
+nv04_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *mem)
  {
-	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
  	struct drm_device *dev = nvbe->dev;
  	struct drm_nouveau_private *dev_priv = dev->dev_private;
  	struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma;
  	unsigned i, j, pte;
+	int r;

  	NV_DEBUG(dev, "pg=0x%lx\n", mem->start);
+	r = nouveau_sgdma_dma_map(ttm);
+	if (r) {
+		return r;
+	}

  	nvbe->offset = mem->start<<  PAGE_SHIFT;
  	pte = (nvbe->offset>>  NV_CTXDMA_PAGE_SHIFT) + 2;
-	for (i = 0; i<  nvbe->nr_pages; i++) {
-		dma_addr_t dma_offset = nvbe->pages[i];
+	for (i = 0; i<  ttm->num_pages; i++) {
+		dma_addr_t dma_offset = ttm->dma_address[i];
  		uint32_t offset_l = lower_32_bits(dma_offset);

  		for (j = 0; j<  PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++, pte++) {
@@ -109,14 +87,13 @@ nv04_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
  		}
  	}

-	nvbe->bound = true;
  	return 0;
  }

  static int
-nv04_sgdma_unbind(struct ttm_backend *be)
+nv04_sgdma_unbind(struct ttm_tt *ttm)
  {
-	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
  	struct drm_device *dev = nvbe->dev;
  	struct drm_nouveau_private *dev_priv = dev->dev_private;
  	struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma;
@@ -124,22 +101,20 @@ nv04_sgdma_unbind(struct ttm_backend *be)

  	NV_DEBUG(dev, "\n");

-	if (!nvbe->bound)
+	if (ttm->state != tt_bound)
  		return 0;

  	pte = (nvbe->offset>>  NV_CTXDMA_PAGE_SHIFT) + 2;
-	for (i = 0; i<  nvbe->nr_pages; i++) {
+	for (i = 0; i<  ttm->num_pages; i++) {
  		for (j = 0; j<  PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++, pte++)
  			nv_wo32(gpuobj, (pte * 4) + 0, 0x00000000);
  	}

-	nvbe->bound = false;
+	nouveau_sgdma_dma_unmap(ttm);
  	return 0;
  }

  static struct ttm_backend_func nv04_sgdma_backend = {
-	.populate		= nouveau_sgdma_populate,
-	.clear			= nouveau_sgdma_clear,
  	.bind			= nv04_sgdma_bind,
  	.unbind			= nv04_sgdma_unbind,
  	.destroy		= nouveau_sgdma_destroy
@@ -158,16 +133,21 @@ nv41_sgdma_flush(struct nouveau_sgdma_be *nvbe)
  }

  static int
-nv41_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
+nv41_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *mem)
  {
-	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
  	struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private;
  	struct nouveau_gpuobj *pgt = dev_priv->gart_info.sg_ctxdma;
-	dma_addr_t *list = nvbe->pages;
+	dma_addr_t *list = ttm->dma_address;
  	u32 pte = mem->start<<  2;
-	u32 cnt = nvbe->nr_pages;
+	u32 cnt = ttm->num_pages;
+	int r;

  	nvbe->offset = mem->start<<  PAGE_SHIFT;
+	r = nouveau_sgdma_dma_map(ttm);
+	if (r) {
+		return r;
+	}

  	while (cnt--) {
  		nv_wo32(pgt, pte, (*list++>>  7) | 1);
@@ -175,18 +155,17 @@ nv41_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
  	}

  	nv41_sgdma_flush(nvbe);
-	nvbe->bound = true;
  	return 0;
  }

  static int
-nv41_sgdma_unbind(struct ttm_backend *be)
+nv41_sgdma_unbind(struct ttm_tt *ttm)
  {
-	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
  	struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private;
  	struct nouveau_gpuobj *pgt = dev_priv->gart_info.sg_ctxdma;
  	u32 pte = (nvbe->offset>>  12)<<  2;
-	u32 cnt = nvbe->nr_pages;
+	u32 cnt = ttm->num_pages;

  	while (cnt--) {
  		nv_wo32(pgt, pte, 0x00000000);
@@ -194,24 +173,23 @@ nv41_sgdma_unbind(struct ttm_backend *be)
  	}

  	nv41_sgdma_flush(nvbe);
-	nvbe->bound = false;
+	nouveau_sgdma_dma_unmap(ttm);
  	return 0;
  }

  static struct ttm_backend_func nv41_sgdma_backend = {
-	.populate		= nouveau_sgdma_populate,
-	.clear			= nouveau_sgdma_clear,
  	.bind			= nv41_sgdma_bind,
  	.unbind			= nv41_sgdma_unbind,
  	.destroy		= nouveau_sgdma_destroy
  };

  static void
-nv44_sgdma_flush(struct nouveau_sgdma_be *nvbe)
+nv44_sgdma_flush(struct ttm_tt *ttm)
  {
+	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
  	struct drm_device *dev = nvbe->dev;

-	nv_wr32(dev, 0x100814, (nvbe->nr_pages - 1)<<  12);
+	nv_wr32(dev, 0x100814, (ttm->num_pages - 1)<<  12);
  	nv_wr32(dev, 0x100808, nvbe->offset | 0x20);
  	if (!nv_wait(dev, 0x100808, 0x00000001, 0x00000001))
  		NV_ERROR(dev, "gart flush timeout: 0x%08x\n",
@@ -270,17 +248,21 @@ nv44_sgdma_fill(struct nouveau_gpuobj *pgt, dma_addr_t *list, u32 base, u32 cnt)
  }

  static int
-nv44_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
+nv44_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *mem)
  {
-	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
  	struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private;
  	struct nouveau_gpuobj *pgt = dev_priv->gart_info.sg_ctxdma;
-	dma_addr_t *list = nvbe->pages;
+	dma_addr_t *list = ttm->dma_address;
  	u32 pte = mem->start<<  2, tmp[4];
-	u32 cnt = nvbe->nr_pages;
-	int i;
+	u32 cnt = ttm->num_pages;
+	int i, r;

  	nvbe->offset = mem->start<<  PAGE_SHIFT;
+	r = nouveau_sgdma_dma_map(ttm);
+	if (r) {
+		return r;
+	}

  	if (pte&  0x0000000c) {
  		u32  max = 4 - ((pte>>  2)&  0x3);
@@ -305,19 +287,18 @@ nv44_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
  	if (cnt)
  		nv44_sgdma_fill(pgt, list, pte, cnt);

-	nv44_sgdma_flush(nvbe);
-	nvbe->bound = true;
+	nv44_sgdma_flush(ttm);
  	return 0;
  }

  static int
-nv44_sgdma_unbind(struct ttm_backend *be)
+nv44_sgdma_unbind(struct ttm_tt *ttm)
  {
-	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
  	struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private;
  	struct nouveau_gpuobj *pgt = dev_priv->gart_info.sg_ctxdma;
  	u32 pte = (nvbe->offset>>  12)<<  2;
-	u32 cnt = nvbe->nr_pages;
+	u32 cnt = ttm->num_pages;

  	if (pte&  0x0000000c) {
  		u32  max = 4 - ((pte>>  2)&  0x3);
@@ -339,55 +320,53 @@ nv44_sgdma_unbind(struct ttm_backend *be)
  	if (cnt)
  		nv44_sgdma_fill(pgt, NULL, pte, cnt);

-	nv44_sgdma_flush(nvbe);
-	nvbe->bound = false;
+	nv44_sgdma_flush(ttm);
+	nouveau_sgdma_dma_unmap(ttm);
  	return 0;
  }

  static struct ttm_backend_func nv44_sgdma_backend = {
-	.populate		= nouveau_sgdma_populate,
-	.clear			= nouveau_sgdma_clear,
  	.bind			= nv44_sgdma_bind,
  	.unbind			= nv44_sgdma_unbind,
  	.destroy		= nouveau_sgdma_destroy
  };

  static int
-nv50_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
+nv50_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *mem)
  {
-	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
  	struct nouveau_mem *node = mem->mm_node;
+	int r;
+
  	/* noop: bound in move_notify() */
-	node->pages = nvbe->pages;
-	nvbe->pages = (dma_addr_t *)node;
-	nvbe->bound = true;
+	r = nouveau_sgdma_dma_map(ttm);
+	if (r) {
+		return r;
+	}
+	node->pages = ttm->dma_address;
  	return 0;
  }

  static int
-nv50_sgdma_unbind(struct ttm_backend *be)
+nv50_sgdma_unbind(struct ttm_tt *ttm)
  {
-	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
-	struct nouveau_mem *node = (struct nouveau_mem *)nvbe->pages;
  	/* noop: unbound in move_notify() */
-	nvbe->pages = node->pages;
-	node->pages = NULL;
-	nvbe->bound = false;
+	nouveau_sgdma_dma_unmap(ttm);
  	return 0;
  }

  static struct ttm_backend_func nv50_sgdma_backend = {
-	.populate		= nouveau_sgdma_populate,
-	.clear			= nouveau_sgdma_clear,
  	.bind			= nv50_sgdma_bind,
  	.unbind			= nv50_sgdma_unbind,
  	.destroy		= nouveau_sgdma_destroy
  };

-struct ttm_backend *
-nouveau_sgdma_init_ttm(struct drm_device *dev)
+struct ttm_tt *
+nouveau_sgdma_create_ttm(struct ttm_bo_device *bdev,
+			 unsigned long size, uint32_t page_flags,
+			 struct page *dummy_read_page)
  {
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev);
+	struct drm_device *dev = dev_priv->dev;
  	struct nouveau_sgdma_be *nvbe;

  	nvbe = kzalloc(sizeof(*nvbe), GFP_KERNEL);
@@ -395,9 +374,12 @@ nouveau_sgdma_init_ttm(struct drm_device *dev)
  		return NULL;

  	nvbe->dev = dev;
+	nvbe->ttm.func = dev_priv->gart_info.func;

-	nvbe->backend.func = dev_priv->gart_info.func;
-	return&nvbe->backend;
+	if (ttm_tt_init(&nvbe->ttm, bdev, size, page_flags, dummy_read_page)) {
+		return NULL;
+	}
+	return&nvbe->ttm;
  }

  int
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index 97c76ae..53ff62b 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -114,24 +114,6 @@ static void radeon_ttm_global_fini(struct radeon_device *rdev)
  	}
  }

-struct ttm_backend *radeon_ttm_backend_create(struct radeon_device *rdev);
-
-static struct ttm_backend*
-radeon_create_ttm_backend_entry(struct ttm_bo_device *bdev)
-{
-	struct radeon_device *rdev;
-
-	rdev = radeon_get_rdev(bdev);
-#if __OS_HAS_AGP
-	if (rdev->flags&  RADEON_IS_AGP) {
-		return ttm_agp_backend_init(bdev, rdev->ddev->agp->bridge);
-	} else
-#endif
-	{
-		return radeon_ttm_backend_create(rdev);
-	}
-}
-
  static int radeon_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags)
  {
  	return 0;
@@ -515,8 +497,93 @@ static bool radeon_sync_obj_signaled(void *sync_obj, void *sync_arg)
  	return radeon_fence_signaled((struct radeon_fence *)sync_obj);
  }

+/*
+ * TTM backend functions.
+ */
+struct radeon_ttm_tt {
+	struct ttm_tt			ttm;
+	struct radeon_device		*rdev;
+	u64				offset;
+};
+
+static int radeon_ttm_backend_bind(struct ttm_tt *ttm,
+				   struct ttm_mem_reg *bo_mem)
+{
+	struct radeon_ttm_tt *gtt;
+	int r;
+
+	gtt = container_of(ttm, struct radeon_ttm_tt, ttm);
+	gtt->offset = (unsigned long)(bo_mem->start<<  PAGE_SHIFT);
+	if (!ttm->num_pages) {
+		WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n",
+		     ttm->num_pages, bo_mem, ttm);
+	}
+	r = radeon_gart_bind(gtt->rdev, gtt->offset,
+			     ttm->num_pages, ttm->pages, ttm->dma_address);
+	if (r) {
+		DRM_ERROR("failed to bind %lu pages at 0x%08X\n",
+			  ttm->num_pages, (unsigned)gtt->offset);
+		return r;
+	}
+	return 0;
+}
+
+static int radeon_ttm_backend_unbind(struct ttm_tt *ttm)
+{
+	struct radeon_ttm_tt *gtt;
+
+	gtt = container_of(ttm, struct radeon_ttm_tt, ttm);
+	radeon_gart_unbind(gtt->rdev, gtt->offset, ttm->num_pages);
+	return 0;
+}
+
+static void radeon_ttm_backend_destroy(struct ttm_tt *ttm)
+{
+	struct radeon_ttm_tt *gtt;
+
+	gtt = container_of(ttm, struct radeon_ttm_tt, ttm);
+	if (ttm->state == tt_bound) {
+		radeon_ttm_backend_unbind(ttm);
+	}
+	kfree(gtt);
+}
+
+static struct ttm_backend_func radeon_backend_func = {
+	.bind =&radeon_ttm_backend_bind,
+	.unbind =&radeon_ttm_backend_unbind,
+	.destroy =&radeon_ttm_backend_destroy,
+};
+
+struct ttm_tt *radeon_ttm_tt_create(struct ttm_bo_device *bdev,
+				    unsigned long size, uint32_t page_flags,
+				    struct page *dummy_read_page)
+{
+	struct radeon_device *rdev;
+	struct radeon_ttm_tt *gtt;
+
+	rdev = radeon_get_rdev(bdev);
+#if __OS_HAS_AGP
+	if (rdev->flags&  RADEON_IS_AGP) {
+		return ttm_agp_tt_create(bdev, rdev->ddev->agp->bridge,
+					 size, page_flags, dummy_read_page);
+	}
+#endif
+
+	gtt = kzalloc(sizeof(struct radeon_ttm_tt), GFP_KERNEL);
+	if (gtt == NULL) {
+		return NULL;
+	}
+	gtt->ttm.func =&radeon_backend_func;
+	gtt->rdev = rdev;
+	if (ttm_tt_init(&gtt->ttm, bdev, size, page_flags, dummy_read_page)) {
+		return NULL;
+	}
+	return&gtt->ttm;
+}
+
+
  static struct ttm_bo_driver radeon_bo_driver = {
-	.create_ttm_backend_entry =&radeon_create_ttm_backend_entry,
+	.ttm_tt_create =&radeon_ttm_tt_create,
  	.invalidate_caches =&radeon_invalidate_caches,
  	.init_mem_type =&radeon_init_mem_type,
  	.evict_flags =&radeon_evict_flags,
@@ -680,123 +747,6 @@ int radeon_mmap(struct file *filp, struct vm_area_struct *vma)
  }


-/*
- * TTM backend functions.
- */
-struct radeon_ttm_backend {
-	struct ttm_backend		backend;
-	struct radeon_device		*rdev;
-	unsigned long			num_pages;
-	struct page			**pages;
-	struct page			*dummy_read_page;
-	dma_addr_t			*dma_addrs;
-	bool				populated;
-	bool				bound;
-	unsigned			offset;
-};
-
-static int radeon_ttm_backend_populate(struct ttm_backend *backend,
-				       unsigned long num_pages,
-				       struct page **pages,
-				       struct page *dummy_read_page,
-				       dma_addr_t *dma_addrs)
-{
-	struct radeon_ttm_backend *gtt;
-
-	gtt = container_of(backend, struct radeon_ttm_backend, backend);
-	gtt->pages = pages;
-	gtt->dma_addrs = dma_addrs;
-	gtt->num_pages = num_pages;
-	gtt->dummy_read_page = dummy_read_page;
-	gtt->populated = true;
-	return 0;
-}
-
-static void radeon_ttm_backend_clear(struct ttm_backend *backend)
-{
-	struct radeon_ttm_backend *gtt;
-
-	gtt = container_of(backend, struct radeon_ttm_backend, backend);
-	gtt->pages = NULL;
-	gtt->dma_addrs = NULL;
-	gtt->num_pages = 0;
-	gtt->dummy_read_page = NULL;
-	gtt->populated = false;
-	gtt->bound = false;
-}
-
-
-static int radeon_ttm_backend_bind(struct ttm_backend *backend,
-				   struct ttm_mem_reg *bo_mem)
-{
-	struct radeon_ttm_backend *gtt;
-	int r;
-
-	gtt = container_of(backend, struct radeon_ttm_backend, backend);
-	gtt->offset = bo_mem->start<<  PAGE_SHIFT;
-	if (!gtt->num_pages) {
-		WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n",
-		     gtt->num_pages, bo_mem, backend);
-	}
-	r = radeon_gart_bind(gtt->rdev, gtt->offset,
-			     gtt->num_pages, gtt->pages, gtt->dma_addrs);
-	if (r) {
-		DRM_ERROR("failed to bind %lu pages at 0x%08X\n",
-			  gtt->num_pages, gtt->offset);
-		return r;
-	}
-	gtt->bound = true;
-	return 0;
-}
-
-static int radeon_ttm_backend_unbind(struct ttm_backend *backend)
-{
-	struct radeon_ttm_backend *gtt;
-
-	gtt = container_of(backend, struct radeon_ttm_backend, backend);
-	radeon_gart_unbind(gtt->rdev, gtt->offset, gtt->num_pages);
-	gtt->bound = false;
-	return 0;
-}
-
-static void radeon_ttm_backend_destroy(struct ttm_backend *backend)
-{
-	struct radeon_ttm_backend *gtt;
-
-	gtt = container_of(backend, struct radeon_ttm_backend, backend);
-	if (gtt->bound) {
-		radeon_ttm_backend_unbind(backend);
-	}
-	kfree(gtt);
-}
-
-static struct ttm_backend_func radeon_backend_func = {
-	.populate =&radeon_ttm_backend_populate,
-	.clear =&radeon_ttm_backend_clear,
-	.bind =&radeon_ttm_backend_bind,
-	.unbind =&radeon_ttm_backend_unbind,
-	.destroy =&radeon_ttm_backend_destroy,
-};
-
-struct ttm_backend *radeon_ttm_backend_create(struct radeon_device *rdev)
-{
-	struct radeon_ttm_backend *gtt;
-
-	gtt = kzalloc(sizeof(struct radeon_ttm_backend), GFP_KERNEL);
-	if (gtt == NULL) {
-		return NULL;
-	}
-	gtt->backend.bdev =&rdev->mman.bdev;
-	gtt->backend.func =&radeon_backend_func;
-	gtt->rdev = rdev;
-	gtt->pages = NULL;
-	gtt->num_pages = 0;
-	gtt->dummy_read_page = NULL;
-	gtt->populated = false;
-	gtt->bound = false;
-	return&gtt->backend;
-}
-
  #define RADEON_DEBUGFS_MEM_TYPES 2

  #if defined(CONFIG_DEBUG_FS)
diff --git a/drivers/gpu/drm/ttm/ttm_agp_backend.c b/drivers/gpu/drm/ttm/ttm_agp_backend.c
index 1c4a72f..14ebd36 100644
--- a/drivers/gpu/drm/ttm/ttm_agp_backend.c
+++ b/drivers/gpu/drm/ttm/ttm_agp_backend.c
@@ -40,45 +40,33 @@
  #include<asm/agp.h>

  struct ttm_agp_backend {
-	struct ttm_backend backend;
+	struct ttm_tt ttm;
  	struct agp_memory *mem;
  	struct agp_bridge_data *bridge;
  };

-static int ttm_agp_populate(struct ttm_backend *backend,
-			    unsigned long num_pages, struct page **pages,
-			    struct page *dummy_read_page,
-			    dma_addr_t *dma_addrs)
+static int ttm_agp_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem)
  {
-	struct ttm_agp_backend *agp_be =
-	    container_of(backend, struct ttm_agp_backend, backend);
-	struct page **cur_page, **last_page = pages + num_pages;
+	struct ttm_agp_backend *agp_be = container_of(ttm, struct ttm_agp_backend, ttm);
+	struct drm_mm_node *node = bo_mem->mm_node;
  	struct agp_memory *mem;
+	int ret, cached = (bo_mem->placement&  TTM_PL_FLAG_CACHED);
+	unsigned i;

-	mem = agp_allocate_memory(agp_be->bridge, num_pages, AGP_USER_MEMORY);
+	mem = agp_allocate_memory(agp_be->bridge, ttm->num_pages, AGP_USER_MEMORY);
  	if (unlikely(mem == NULL))
  		return -ENOMEM;

  	mem->page_count = 0;
-	for (cur_page = pages; cur_page<  last_page; ++cur_page) {
-		struct page *page = *cur_page;
+	for (i = 0; i<  ttm->num_pages; i++) {
+		struct page *page = ttm->pages[i];
+
  		if (!page)
-			page = dummy_read_page;
+			page = ttm->dummy_read_page;

  		mem->pages[mem->page_count++] = page;
  	}
  	agp_be->mem = mem;
-	return 0;
-}
-
-static int ttm_agp_bind(struct ttm_backend *backend, struct ttm_mem_reg *bo_mem)
-{
-	struct ttm_agp_backend *agp_be =
-	    container_of(backend, struct ttm_agp_backend, backend);
-	struct drm_mm_node *node = bo_mem->mm_node;
-	struct agp_memory *mem = agp_be->mem;
-	int cached = (bo_mem->placement&  TTM_PL_FLAG_CACHED);
-	int ret;

  	mem->is_flushed = 1;
  	mem->type = (cached) ? AGP_USER_CACHED_MEMORY : AGP_USER_MEMORY;
@@ -90,50 +78,38 @@ static int ttm_agp_bind(struct ttm_backend *backend, struct ttm_mem_reg *bo_mem)
  	return ret;
  }

-static int ttm_agp_unbind(struct ttm_backend *backend)
+static int ttm_agp_unbind(struct ttm_tt *ttm)
  {
-	struct ttm_agp_backend *agp_be =
-	    container_of(backend, struct ttm_agp_backend, backend);
-
-	if (agp_be->mem->is_bound)
-		return agp_unbind_memory(agp_be->mem);
-	else
-		return 0;
-}
+	struct ttm_agp_backend *agp_be = container_of(ttm, struct ttm_agp_backend, ttm);

-static void ttm_agp_clear(struct ttm_backend *backend)
-{
-	struct ttm_agp_backend *agp_be =
-	    container_of(backend, struct ttm_agp_backend, backend);
-	struct agp_memory *mem = agp_be->mem;
-
-	if (mem) {
-		ttm_agp_unbind(backend);
-		agp_free_memory(mem);
+	if (agp_be->mem) {
+		if (agp_be->mem->is_bound)
+			return agp_unbind_memory(agp_be->mem);
+		agp_free_memory(agp_be->mem);
+		agp_be->mem = NULL;
  	}
-	agp_be->mem = NULL;
+	return 0;
  }

-static void ttm_agp_destroy(struct ttm_backend *backend)
+static void ttm_agp_destroy(struct ttm_tt *ttm)
  {
-	struct ttm_agp_backend *agp_be =
-	    container_of(backend, struct ttm_agp_backend, backend);
+	struct ttm_agp_backend *agp_be = container_of(ttm, struct ttm_agp_backend, ttm);

  	if (agp_be->mem)
-		ttm_agp_clear(backend);
+		ttm_agp_unbind(ttm);
  	kfree(agp_be);
  }

  static struct ttm_backend_func ttm_agp_func = {
-	.populate = ttm_agp_populate,
-	.clear = ttm_agp_clear,
  	.bind = ttm_agp_bind,
  	.unbind = ttm_agp_unbind,
  	.destroy = ttm_agp_destroy,
  };

-struct ttm_backend *ttm_agp_backend_init(struct ttm_bo_device *bdev,
-					 struct agp_bridge_data *bridge)
+struct ttm_tt *ttm_agp_tt_create(struct ttm_bo_device *bdev,
+				 struct agp_bridge_data *bridge,
+				 unsigned long size, uint32_t page_flags,
+				 struct page *dummy_read_page)
  {
  	struct ttm_agp_backend *agp_be;

@@ -143,10 +119,14 @@ struct ttm_backend *ttm_agp_backend_init(struct ttm_bo_device *bdev,

  	agp_be->mem = NULL;
  	agp_be->bridge = bridge;
-	agp_be->backend.func =&ttm_agp_func;
-	agp_be->backend.bdev = bdev;
-	return&agp_be->backend;
+	agp_be->ttm.func =&ttm_agp_func;
+
+	if (ttm_tt_init(&agp_be->ttm, bdev, size, page_flags, dummy_read_page)) {
+		return NULL;
+	}
+
+	return&agp_be->ttm;
  }
-EXPORT_SYMBOL(ttm_agp_backend_init);
+EXPORT_SYMBOL(ttm_agp_tt_create);

  #endif
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 4bde335..cb73527 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -337,8 +337,8 @@ static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, bool zero_alloc)
  		if (zero_alloc)
  			page_flags |= TTM_PAGE_FLAG_ZERO_ALLOC;
  	case ttm_bo_type_kernel:
-		bo->ttm = ttm_tt_create(bdev, bo->num_pages<<  PAGE_SHIFT,
-					page_flags, glob->dummy_read_page);
+		bo->ttm = bdev->driver->ttm_tt_create(bdev, bo->num_pages<<  PAGE_SHIFT,
+						      page_flags, glob->dummy_read_page);
  		if (unlikely(bo->ttm == NULL))
  			ret = -ENOMEM;
  		break;
@@ -1437,10 +1437,7 @@ int ttm_bo_global_init(struct drm_global_reference *ref)
  		goto out_no_shrink;
  	}

-	glob->ttm_bo_extra_size =
-		ttm_round_pot(sizeof(struct ttm_tt)) +
-		ttm_round_pot(sizeof(struct ttm_backend));
-
+	glob->ttm_bo_extra_size = ttm_round_pot(sizeof(struct ttm_tt));
  	glob->ttm_bo_size = glob->ttm_bo_extra_size +
  		ttm_round_pot(sizeof(struct ttm_buffer_object));

diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index 58ea7dc..b55e132 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -103,7 +103,6 @@ struct page *ttm_tt_get_page(struct ttm_tt *ttm, int index)
  int ttm_tt_populate(struct ttm_tt *ttm)
  {
  	struct ttm_mem_global *mem_glob = ttm->glob->mem_glob;
-	struct ttm_backend *be;
  	int ret;

  	if (ttm->state != tt_unpopulated)
@@ -115,8 +114,6 @@ int ttm_tt_populate(struct ttm_tt *ttm)
  			return ret;
  	}

-	be = ttm->be;
-
  	ret = ttm_get_pages(ttm->pages, ttm->num_pages, ttm->page_flags,
  			    ttm->caching_state, ttm->dma_address);
  	if (ret != 0)
@@ -129,8 +126,6 @@ int ttm_tt_populate(struct ttm_tt *ttm)
  		return -ENOMEM;
  	}

-	be->func->populate(be, ttm->num_pages, ttm->pages,
-			   ttm->dummy_read_page, ttm->dma_address);
  	ttm->state = tt_unbound;
  	return 0;
  }
@@ -239,12 +234,8 @@ EXPORT_SYMBOL(ttm_tt_set_placement_caching);

  static void ttm_tt_free_alloced_pages(struct ttm_tt *ttm)
  {
-	struct ttm_backend *be = ttm->be;
  	struct ttm_mem_global *glob = ttm->glob->mem_glob;

-	if (be)
-		be->func->clear(be);
-
  	ttm_mem_global_free_pages(glob, ttm->pages, ttm->num_pages);
  	ttm_put_pages(ttm->pages, ttm->num_pages, ttm->page_flags,
  			ttm->caching_state, ttm->dma_address);
@@ -253,20 +244,11 @@ static void ttm_tt_free_alloced_pages(struct ttm_tt *ttm)

  void ttm_tt_destroy(struct ttm_tt *ttm)
  {
-	struct ttm_backend *be;
-
  	if (unlikely(ttm == NULL))
  		return;

-	be = ttm->be;
-	if (likely(be != NULL)) {
-		be->func->destroy(be);
-		ttm->be = NULL;
-	}
-
  	if (likely(ttm->pages != NULL)) {
  		ttm_tt_free_alloced_pages(ttm);
-
  		ttm_tt_free_page_directory(ttm);
  	}

@@ -274,52 +256,38 @@ void ttm_tt_destroy(struct ttm_tt *ttm)
  	    ttm->swap_storage)
  		fput(ttm->swap_storage);

-	kfree(ttm);
+	ttm->swap_storage = NULL;
+	ttm->func->destroy(ttm);
  }

-struct ttm_tt *ttm_tt_create(struct ttm_bo_device *bdev, unsigned long size,
-			     uint32_t page_flags, struct page *dummy_read_page)
+int ttm_tt_init(struct ttm_tt *ttm, struct ttm_bo_device *bdev,
+		unsigned long size, uint32_t page_flags,
+		struct page *dummy_read_page)
  {
-	struct ttm_bo_driver *bo_driver = bdev->driver;
-	struct ttm_tt *ttm;
-
-	if (!bo_driver)
-		return NULL;
-
-	ttm = kzalloc(sizeof(*ttm), GFP_KERNEL);
-	if (!ttm)
-		return NULL;
-
+	ttm->bdev = bdev;
  	ttm->glob = bdev->glob;
  	ttm->num_pages = (size + PAGE_SIZE - 1)>>  PAGE_SHIFT;
  	ttm->caching_state = tt_cached;
  	ttm->page_flags = page_flags;
-
  	ttm->dummy_read_page = dummy_read_page;
+	ttm->state = tt_unpopulated;

  	ttm_tt_alloc_page_directory(ttm);
  	if (!ttm->pages || !ttm->dma_address) {
  		ttm_tt_destroy(ttm);
  		printk(KERN_ERR TTM_PFX "Failed allocating page table\n");
-		return NULL;
-	}
-	ttm->be = bo_driver->create_ttm_backend_entry(bdev);
-	if (!ttm->be) {
-		ttm_tt_destroy(ttm);
-		printk(KERN_ERR TTM_PFX "Failed creating ttm backend entry\n");
-		return NULL;
+		return -ENOMEM;
  	}
-	ttm->state = tt_unpopulated;
-	return ttm;
+	return 0;
  }
+EXPORT_SYMBOL(ttm_tt_init);

  void ttm_tt_unbind(struct ttm_tt *ttm)
  {
  	int ret;
-	struct ttm_backend *be = ttm->be;

  	if (ttm->state == tt_bound) {
-		ret = be->func->unbind(be);
+		ret = ttm->func->unbind(ttm);
  		BUG_ON(ret);
  		ttm->state = tt_unbound;
  	}
@@ -328,7 +296,6 @@ void ttm_tt_unbind(struct ttm_tt *ttm)
  int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem)
  {
  	int ret = 0;
-	struct ttm_backend *be;

  	if (!ttm)
  		return -EINVAL;
@@ -336,13 +303,11 @@ int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem)
  	if (ttm->state == tt_bound)
  		return 0;

-	be = ttm->be;
-
  	ret = ttm_tt_populate(ttm);
  	if (ret)
  		return ret;

-	ret = be->func->bind(be, bo_mem);
+	ret = ttm->func->bind(ttm, bo_mem);
  	if (unlikely(ret != 0))
  		return ret;

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
index 5a72ed9..cc72435 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
@@ -139,85 +139,61 @@ struct ttm_placement vmw_srf_placement = {
  	.busy_placement = gmr_vram_placement_flags
  };

-struct vmw_ttm_backend {
-	struct ttm_backend backend;
-	struct page **pages;
-	unsigned long num_pages;
+struct vmw_ttm_tt {
+	struct ttm_tt ttm;
  	struct vmw_private *dev_priv;
  	int gmr_id;
  };

-static int vmw_ttm_populate(struct ttm_backend *backend,
-			    unsigned long num_pages, struct page **pages,
-			    struct page *dummy_read_page,
-			    dma_addr_t *dma_addrs)
+static int vmw_ttm_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem)
  {
-	struct vmw_ttm_backend *vmw_be =
-	    container_of(backend, struct vmw_ttm_backend, backend);
-
-	vmw_be->pages = pages;
-	vmw_be->num_pages = num_pages;
-
-	return 0;
-}
-
-static int vmw_ttm_bind(struct ttm_backend *backend, struct ttm_mem_reg *bo_mem)
-{
-	struct vmw_ttm_backend *vmw_be =
-	    container_of(backend, struct vmw_ttm_backend, backend);
+	struct vmw_ttm_tt *vmw_be = container_of(ttm, struct vmw_ttm_tt, ttm);

  	vmw_be->gmr_id = bo_mem->start;

-	return vmw_gmr_bind(vmw_be->dev_priv, vmw_be->pages,
-			    vmw_be->num_pages, vmw_be->gmr_id);
+	return vmw_gmr_bind(vmw_be->dev_priv, ttm->pages,
+			    ttm->num_pages, vmw_be->gmr_id);
  }

-static int vmw_ttm_unbind(struct ttm_backend *backend)
+static int vmw_ttm_unbind(struct ttm_tt *ttm)
  {
-	struct vmw_ttm_backend *vmw_be =
-	    container_of(backend, struct vmw_ttm_backend, backend);
+	struct vmw_ttm_tt *vmw_be = container_of(ttm, struct vmw_ttm_tt, ttm);

  	vmw_gmr_unbind(vmw_be->dev_priv, vmw_be->gmr_id);
  	return 0;
  }

-static void vmw_ttm_clear(struct ttm_backend *backend)
+static void vmw_ttm_destroy(struct ttm_tt *ttm)
  {
-	struct vmw_ttm_backend *vmw_be =
-		container_of(backend, struct vmw_ttm_backend, backend);
-
-	vmw_be->pages = NULL;
-	vmw_be->num_pages = 0;
-}
-
-static void vmw_ttm_destroy(struct ttm_backend *backend)
-{
-	struct vmw_ttm_backend *vmw_be =
-	    container_of(backend, struct vmw_ttm_backend, backend);
+	struct vmw_ttm_tt *vmw_be = container_of(ttm, struct vmw_ttm_tt, ttm);

  	kfree(vmw_be);
  }

  static struct ttm_backend_func vmw_ttm_func = {
-	.populate = vmw_ttm_populate,
-	.clear = vmw_ttm_clear,
  	.bind = vmw_ttm_bind,
  	.unbind = vmw_ttm_unbind,
  	.destroy = vmw_ttm_destroy,
  };

-struct ttm_backend *vmw_ttm_backend_init(struct ttm_bo_device *bdev)
+struct ttm_tt *vmw_ttm_tt_create(struct ttm_bo_device *bdev,
+				 unsigned long size, uint32_t page_flags,
+				 struct page *dummy_read_page)
  {
-	struct vmw_ttm_backend *vmw_be;
+	struct vmw_ttm_tt *vmw_be;

  	vmw_be = kmalloc(sizeof(*vmw_be), GFP_KERNEL);
  	if (!vmw_be)
  		return NULL;

-	vmw_be->backend.func =&vmw_ttm_func;
+	vmw_be->ttm.func =&vmw_ttm_func;
  	vmw_be->dev_priv = container_of(bdev, struct vmw_private, bdev);

-	return&vmw_be->backend;
+	if (ttm_tt_init(&vmw_be->ttm, bdev, size, page_flags, dummy_read_page)) {
+		return NULL;
+	}
+
+	return&vmw_be->ttm;
  }

  int vmw_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags)
@@ -357,7 +333,7 @@ static int vmw_sync_obj_wait(void *sync_obj, void *sync_arg,
  }

  struct ttm_bo_driver vmw_bo_driver = {
-	.create_ttm_backend_entry = vmw_ttm_backend_init,
+	.ttm_tt_create =&vmw_ttm_tt_create,
  	.invalidate_caches = vmw_invalidate_caches,
  	.init_mem_type = vmw_init_mem_type,
  	.evict_flags = vmw_evict_flags,
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h
index 6d17140..6b8c5cd 100644
--- a/include/drm/ttm/ttm_bo_driver.h
+++ b/include/drm/ttm/ttm_bo_driver.h
@@ -43,36 +43,9 @@ struct ttm_backend;

  struct ttm_backend_func {
  	/**
-	 * struct ttm_backend_func member populate
-	 *
-	 * @backend: Pointer to a struct ttm_backend.
-	 * @num_pages: Number of pages to populate.
-	 * @pages: Array of pointers to ttm pages.
-	 * @dummy_read_page: Page to be used instead of NULL pages in the
-	 * array @pages.
-	 * @dma_addrs: Array of DMA (bus) address of the ttm pages.
-	 *
-	 * Populate the backend with ttm pages. Depending on the backend,
-	 * it may or may not copy the @pages array.
-	 */
-	int (*populate) (struct ttm_backend *backend,
-			 unsigned long num_pages, struct page **pages,
-			 struct page *dummy_read_page,
-			 dma_addr_t *dma_addrs);
-	/**
-	 * struct ttm_backend_func member clear
-	 *
-	 * @backend: Pointer to a struct ttm_backend.
-	 *
-	 * This is an "unpopulate" function. Release all resources
-	 * allocated with populate.
-	 */
-	void (*clear) (struct ttm_backend *backend);
-
-	/**
  	 * struct ttm_backend_func member bind
  	 *
-	 * @backend: Pointer to a struct ttm_backend.
+	 * @ttm: Pointer to a struct ttm_tt.
  	 * @bo_mem: Pointer to a struct ttm_mem_reg describing the
  	 * memory type and location for binding.
  	 *
@@ -80,40 +53,27 @@ struct ttm_backend_func {
  	 * indicated by @bo_mem. This function should be able to handle
  	 * differences between aperture and system page sizes.
  	 */
-	int (*bind) (struct ttm_backend *backend, struct ttm_mem_reg *bo_mem);
+	int (*bind) (struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem);

  	/**
  	 * struct ttm_backend_func member unbind
  	 *
-	 * @backend: Pointer to a struct ttm_backend.
+	 * @ttm: Pointer to a struct ttm_tt.
  	 *
  	 * Unbind previously bound backend pages. This function should be
  	 * able to handle differences between aperture and system page sizes.
  	 */
-	int (*unbind) (struct ttm_backend *backend);
+	int (*unbind) (struct ttm_tt *ttm);

  	/**
  	 * struct ttm_backend_func member destroy
  	 *
-	 * @backend: Pointer to a struct ttm_backend.
+	 * @ttm: Pointer to a struct ttm_tt.
  	 *
-	 * Destroy the backend.
+	 * Destroy the backend. This will be call back from ttm_tt_destroy so
+	 * don't call ttm_tt_destroy from the callback or infinite loop.
  	 */
-	void (*destroy) (struct ttm_backend *backend);
-};
-
-/**
- * struct ttm_backend
- *
- * @bdev: Pointer to a struct ttm_bo_device.
- * @func: Pointer to a struct ttm_backend_func that describes
- * the backend methods.
- *
- */
-
-struct ttm_backend {
-	struct ttm_bo_device *bdev;
-	struct ttm_backend_func *func;
+	void (*destroy) (struct ttm_tt *ttm);
  };

  #define TTM_PAGE_FLAG_WRITE           (1<<  3)
@@ -131,6 +91,9 @@ enum ttm_caching_state {
  /**
   * struct ttm_tt
   *
+ * @bdev: Pointer to a struct ttm_bo_device.
+ * @func: Pointer to a struct ttm_backend_func that describes
+ * the backend methods.
   * @dummy_read_page: Page to map where the ttm_tt page array contains a NULL
   * pointer.
   * @pages: Array of pages backing the data.
@@ -148,6 +111,8 @@ enum ttm_caching_state {
   */

  struct ttm_tt {
+	struct ttm_bo_device *bdev;
+	struct ttm_backend_func *func;
  	struct page *dummy_read_page;
  	struct page **pages;
  	uint32_t page_flags;
@@ -336,15 +301,22 @@ struct ttm_mem_type_manager {

  struct ttm_bo_driver {
  	/**
-	 * struct ttm_bo_driver member create_ttm_backend_entry
+	 * ttm_tt_create
  	 *
-	 * @bdev: The buffer object device.
+	 * @bdev: pointer to a struct ttm_bo_device:
+	 * @size: Size of the data needed backing.
+	 * @page_flags: Page flags as identified by TTM_PAGE_FLAG_XX flags.
+	 * @dummy_read_page: See struct ttm_bo_device.
  	 *
-	 * Create a driver specific struct ttm_backend.
+	 * Create a struct ttm_tt to back data with system memory pages.
+	 * No pages are actually allocated.
+	 * Returns:
+	 * NULL: Out of memory.
  	 */
-
-	struct ttm_backend *(*create_ttm_backend_entry)
-	 (struct ttm_bo_device *bdev);
+	struct ttm_tt *(*ttm_tt_create)(struct ttm_bo_device *bdev,
+					unsigned long size,
+					uint32_t page_flags,
+					struct page *dummy_read_page);

  	/**
  	 * struct ttm_bo_driver member invalidate_caches
@@ -585,8 +557,9 @@ ttm_flag_masked(uint32_t *old, uint32_t new, uint32_t mask)
  }

  /**
- * ttm_tt_create
+ * ttm_tt_init
   *
+ * @ttm: The struct ttm_tt.
   * @bdev: pointer to a struct ttm_bo_device:
   * @size: Size of the data needed backing.
   * @page_flags: Page flags as identified by TTM_PAGE_FLAG_XX flags.
@@ -597,10 +570,9 @@ ttm_flag_masked(uint32_t *old, uint32_t new, uint32_t mask)
   * Returns:
   * NULL: Out of memory.
   */
-extern struct ttm_tt *ttm_tt_create(struct ttm_bo_device *bdev,
-				    unsigned long size,
-				    uint32_t page_flags,
-				    struct page *dummy_read_page);
+extern int ttm_tt_init(struct ttm_tt *ttm, struct ttm_bo_device *bdev,
+			unsigned long size, uint32_t page_flags,
+			struct page *dummy_read_page);

  /**
   * ttm_ttm_bind:
@@ -626,7 +598,7 @@ extern int ttm_tt_populate(struct ttm_tt *ttm);
   *
   * @ttm: The struct ttm_tt.
   *
- * Unbind, unpopulate and destroy a struct ttm_tt.
+ * Unbind, unpopulate and destroy common struct ttm_tt.
   */
  extern void ttm_tt_destroy(struct ttm_tt *ttm);

@@ -1013,17 +985,23 @@ extern const struct ttm_mem_type_manager_func ttm_bo_manager_func;
  #include<linux/agp_backend.h>

  /**
- * ttm_agp_backend_init
+ * ttm_agp_tt_create
   *
   * @bdev: Pointer to a struct ttm_bo_device.
   * @bridge: The agp bridge this device is sitting on.
+ * @size: Size of the data needed backing.
+ * @page_flags: Page flags as identified by TTM_PAGE_FLAG_XX flags.
+ * @dummy_read_page: See struct ttm_bo_device.
+ *
   *
   * Create a TTM backend that uses the indicated AGP bridge as an aperture
   * for TT memory. This function uses the linux agpgart interface to
   * bind and unbind memory backing a ttm_tt.
   */
-extern struct ttm_backend *ttm_agp_backend_init(struct ttm_bo_device *bdev,
-						struct agp_bridge_data *bridge);
+extern struct ttm_tt *ttm_agp_tt_create(struct ttm_bo_device *bdev,
+					struct agp_bridge_data *bridge,
+					unsigned long size, uint32_t page_flags,
+					struct page *dummy_read_page);
  #endif

  #endif

_______________________________________________
dri-devel mailing list
dri-devel@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux