diff options
author | Dave Airlie <airlied@redhat.com> | 2012-05-18 10:40:33 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-05-23 05:45:57 -0400 |
commit | 51ab7ba2673758561074184795bba5bac780a038 (patch) | |
tree | 698c399d22524b5ec018af82c89d6c5c8ff422a3 | |
parent | 4d93914ae3db4a897ead4b1e33eca7cdfff4c6f7 (diff) |
drm/prime: introduce sg->pages/addr arrays helper
the ttm drivers need this currently, in order to get fault handling
working and efficient.
It also allows addrs to be NULL for devices like udl.
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r-- | drivers/gpu/drm/drm_prime.c | 36 | ||||
-rw-r--r-- | include/drm/drmP.h | 2 |
2 files changed, 38 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 1bdf2b54eaf6..20dbf2c45385 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c | |||
@@ -227,6 +227,42 @@ out: | |||
227 | } | 227 | } |
228 | EXPORT_SYMBOL(drm_prime_pages_to_sg); | 228 | EXPORT_SYMBOL(drm_prime_pages_to_sg); |
229 | 229 | ||
230 | /* export an sg table into an array of pages and addresses | ||
231 | this is currently required by the TTM driver in order to do correct fault | ||
232 | handling */ | ||
233 | int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages, | ||
234 | dma_addr_t *addrs, int max_pages) | ||
235 | { | ||
236 | unsigned count; | ||
237 | struct scatterlist *sg; | ||
238 | struct page *page; | ||
239 | u32 len, offset; | ||
240 | int pg_index; | ||
241 | dma_addr_t addr; | ||
242 | |||
243 | pg_index = 0; | ||
244 | for_each_sg(sgt->sgl, sg, sgt->nents, count) { | ||
245 | len = sg->length; | ||
246 | offset = sg->offset; | ||
247 | page = sg_page(sg); | ||
248 | addr = sg_dma_address(sg); | ||
249 | |||
250 | while (len > 0) { | ||
251 | if (WARN_ON(pg_index >= max_pages)) | ||
252 | return -1; | ||
253 | pages[pg_index] = page; | ||
254 | if (addrs) | ||
255 | addrs[pg_index] = addr; | ||
256 | |||
257 | page++; | ||
258 | addr += PAGE_SIZE; | ||
259 | len -= PAGE_SIZE; | ||
260 | pg_index++; | ||
261 | } | ||
262 | } | ||
263 | return 0; | ||
264 | } | ||
265 | EXPORT_SYMBOL(drm_prime_sg_to_page_addr_arrays); | ||
230 | /* helper function to cleanup a GEM/prime object */ | 266 | /* helper function to cleanup a GEM/prime object */ |
231 | void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg) | 267 | void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg) |
232 | { | 268 | { |
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 15d91798dd31..31ad880ca2ef 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
@@ -1558,6 +1558,8 @@ extern int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data, | |||
1558 | extern int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, | 1558 | extern int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, |
1559 | struct drm_file *file_priv); | 1559 | struct drm_file *file_priv); |
1560 | 1560 | ||
1561 | extern int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages, | ||
1562 | dma_addr_t *addrs, int max_pages); | ||
1561 | extern struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages); | 1563 | extern struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages); |
1562 | extern void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg); | 1564 | extern void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg); |
1563 | 1565 | ||