On Thu, Nov 03, 2011 at 07:39:11PM -0400, 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. Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> > > Signed-off-by: Jerome Glisse <jglisse@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(>t->ttm, bdev, size, page_flags, dummy_read_page)) { > + return NULL; > + } > + return >t->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 >t->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 > -- > 1.7.7.1 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel