static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo) { struct scatterlist *s; unsigned int i; bo->pages = drm_gem_get_pages(&bo->gem); if (IS_ERR(bo->pages)) return PTR_ERR(bo->pages); bo->num_pages = bo->gem.size >> PAGE_SHIFT; bo->sgt = drm_prime_pages_to_sg(bo->pages, bo->num_pages); if (IS_ERR(bo->sgt)) goto put_pages; /* * Fake up the SG table so that dma_sync_sg_for_device() can be used * to flush the pages associated with it. * * TODO: Replace this by drm_clflash_sg() once it can be implemented * without relying on symbols that are not exported. */ for_each_sg(bo->sgt->sgl, s, bo->sgt->nents, i) sg_dma_address(s) = sg_phys(s); dma_sync_sg_for_device(drm->dev, bo->sgt->sgl, bo->sgt->nents, DMA_TO_DEVICE); return 0; put_pages: drm_gem_put_pages(&bo->gem, bo->pages, false, false); return PTR_ERR(bo->sgt); }
/** ensure backing pages are allocated */ static int omap_gem_attach_pages(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; struct omap_gem_object *omap_obj = to_omap_bo(obj); struct page **pages; int npages = obj->size >> PAGE_SHIFT; int i, ret; dma_addr_t *addrs; WARN_ON(omap_obj->pages); /* TODO: __GFP_DMA32 .. but somehow GFP_HIGHMEM is coming from the * mapping_gfp_mask(mapping) which conflicts w/ GFP_DMA32.. probably * we actually want CMA memory for it all anyways.. */ pages = drm_gem_get_pages(obj, GFP_KERNEL); if (IS_ERR(pages)) { dev_err(obj->dev->dev, "could not get pages: %ld\n", PTR_ERR(pages)); return PTR_ERR(pages); } /* for non-cached buffers, ensure the new pages are clean because * DSS, GPU, etc. are not cache coherent: */ if (omap_obj->flags & (OMAP_BO_WC|OMAP_BO_UNCACHED)) { addrs = kmalloc(npages * sizeof(*addrs), GFP_KERNEL); if (!addrs) { ret = -ENOMEM; goto free_pages; } for (i = 0; i < npages; i++) { addrs[i] = dma_map_page(dev->dev, pages[i], 0, PAGE_SIZE, DMA_BIDIRECTIONAL); } } else { addrs = kzalloc(npages * sizeof(*addrs), GFP_KERNEL); if (!addrs) { ret = -ENOMEM; goto free_pages; } } omap_obj->addrs = addrs; omap_obj->pages = pages; return 0; free_pages: drm_gem_put_pages(obj, pages, true, false); return ret; }
/** ensure backing pages are allocated */ static int omap_gem_attach_pages(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; struct omap_gem_object *omap_obj = to_omap_bo(obj); struct page **pages; int npages = obj->size >> PAGE_SHIFT; int i, ret; dma_addr_t *addrs; WARN_ON(omap_obj->pages); pages = drm_gem_get_pages(obj); if (IS_ERR(pages)) { dev_err(obj->dev->dev, "could not get pages: %ld\n", PTR_ERR(pages)); return PTR_ERR(pages); } /* for non-cached buffers, ensure the new pages are clean because * DSS, GPU, etc. are not cache coherent: */ if (omap_obj->flags & (OMAP_BO_WC|OMAP_BO_UNCACHED)) { addrs = kmalloc(npages * sizeof(*addrs), GFP_KERNEL); if (!addrs) { ret = -ENOMEM; goto free_pages; } for (i = 0; i < npages; i++) { addrs[i] = dma_map_page(dev->dev, pages[i], 0, PAGE_SIZE, DMA_BIDIRECTIONAL); } } else { addrs = kzalloc(npages * sizeof(*addrs), GFP_KERNEL); if (!addrs) { ret = -ENOMEM; goto free_pages; } } omap_obj->addrs = addrs; omap_obj->pages = pages; return 0; free_pages: drm_gem_put_pages(obj, pages, true, false); return ret; }
int udl_gem_get_pages(struct udl_gem_object *obj) { struct page **pages; if (obj->pages) return 0; pages = drm_gem_get_pages(&obj->base); if (IS_ERR(pages)) return PTR_ERR(pages); obj->pages = pages; return 0; }
static int udl_gem_get_pages(struct udl_gem_object *obj, gfp_t gfpmask) { struct page **pages; if (obj->pages) return 0; pages = drm_gem_get_pages(&obj->base, gfpmask); if (IS_ERR(pages)) return PTR_ERR(pages); obj->pages = pages; return 0; }
static int rockchip_gem_get_pages(struct rockchip_gem_object *rk_obj) { struct drm_device *drm = rk_obj->base.dev; int ret, i; struct scatterlist *s; rk_obj->pages = drm_gem_get_pages(&rk_obj->base); if (IS_ERR(rk_obj->pages)) return PTR_ERR(rk_obj->pages); rk_obj->num_pages = rk_obj->base.size >> PAGE_SHIFT; rk_obj->sgt = drm_prime_pages_to_sg(rk_obj->pages, rk_obj->num_pages); if (IS_ERR(rk_obj->sgt)) { ret = PTR_ERR(rk_obj->sgt); goto err_put_pages; } /* * Fake up the SG table so that dma_sync_sg_for_device() can be used * to flush the pages associated with it. * * TODO: Replace this by drm_clflush_sg() once it can be implemented * without relying on symbols that are not exported. */ for_each_sg(rk_obj->sgt->sgl, s, rk_obj->sgt->nents, i) sg_dma_address(s) = sg_phys(s); dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl, rk_obj->sgt->nents, DMA_TO_DEVICE); return 0; err_put_pages: drm_gem_put_pages(&rk_obj->base, rk_obj->pages, false, false); return ret; }