aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/ttm/ttm_tt.c
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2011-11-01 20:46:13 -0400
committerDave Airlie <airlied@redhat.com>2011-12-06 05:39:17 -0500
commit649bf3ca77343e3be1e0af8e21356fa569b1abd9 (patch)
tree01ad6a5f3f74b087cb791f5965d3190916975789 /drivers/gpu/drm/ttm/ttm_tt.c
parent822c4d9ae0d55a4fcea9f0a462bc6406a06692e2 (diff)
drm/ttm: merge ttm_backend and ttm_tt V5
ttm_backend will only exist with a ttm_tt, and ttm_tt will only be of interest when bound to a backend. Merge them to avoid code and data duplication. V2 Rebase on top of memory accounting overhaul V3 Rebase on top of more memory accounting changes V4 Rebase on top of no memory account changes (where/when is my delorean when i need it ?) V5 make sure ttm is unbound before destroying, change commit message on suggestion from Tormod Volden Signed-off-by: Jerome Glisse <jglisse@redhat.com> Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
Diffstat (limited to 'drivers/gpu/drm/ttm/ttm_tt.c')
-rw-r--r--drivers/gpu/drm/ttm/ttm_tt.c59
1 files changed, 14 insertions, 45 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index 6e079dedfc4f..fbc90dce1de8 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -105,7 +105,6 @@ int ttm_tt_populate(struct ttm_tt *ttm)
105{ 105{
106 struct page *page; 106 struct page *page;
107 unsigned long i; 107 unsigned long i;
108 struct ttm_backend *be;
109 int ret; 108 int ret;
110 109
111 if (ttm->state != tt_unpopulated) 110 if (ttm->state != tt_unpopulated)
@@ -117,16 +116,11 @@ int ttm_tt_populate(struct ttm_tt *ttm)
117 return ret; 116 return ret;
118 } 117 }
119 118
120 be = ttm->be;
121
122 for (i = 0; i < ttm->num_pages; ++i) { 119 for (i = 0; i < ttm->num_pages; ++i) {
123 page = __ttm_tt_get_page(ttm, i); 120 page = __ttm_tt_get_page(ttm, i);
124 if (!page) 121 if (!page)
125 return -ENOMEM; 122 return -ENOMEM;
126 } 123 }
127
128 be->func->populate(be, ttm->num_pages, ttm->pages,
129 ttm->dummy_read_page, ttm->dma_address);
130 ttm->state = tt_unbound; 124 ttm->state = tt_unbound;
131 return 0; 125 return 0;
132} 126}
@@ -235,11 +229,8 @@ EXPORT_SYMBOL(ttm_tt_set_placement_caching);
235 229
236static void ttm_tt_free_alloced_pages(struct ttm_tt *ttm) 230static void ttm_tt_free_alloced_pages(struct ttm_tt *ttm)
237{ 231{
238 struct ttm_backend *be = ttm->be;
239 unsigned i; 232 unsigned i;
240 233
241 if (be)
242 be->func->clear(be);
243 for (i = 0; i < ttm->num_pages; ++i) { 234 for (i = 0; i < ttm->num_pages; ++i) {
244 if (ttm->pages[i]) { 235 if (ttm->pages[i]) {
245 ttm_mem_global_free_page(ttm->glob->mem_glob, 236 ttm_mem_global_free_page(ttm->glob->mem_glob,
@@ -253,20 +244,15 @@ static void ttm_tt_free_alloced_pages(struct ttm_tt *ttm)
253 244
254void ttm_tt_destroy(struct ttm_tt *ttm) 245void ttm_tt_destroy(struct ttm_tt *ttm)
255{ 246{
256 struct ttm_backend *be;
257
258 if (unlikely(ttm == NULL)) 247 if (unlikely(ttm == NULL))
259 return; 248 return;
260 249
261 be = ttm->be; 250 if (ttm->state == tt_bound) {
262 if (likely(be != NULL)) { 251 ttm_tt_unbind(ttm);
263 be->func->destroy(be);
264 ttm->be = NULL;
265 } 252 }
266 253
267 if (likely(ttm->pages != NULL)) { 254 if (likely(ttm->pages != NULL)) {
268 ttm_tt_free_alloced_pages(ttm); 255 ttm_tt_free_alloced_pages(ttm);
269
270 ttm_tt_free_page_directory(ttm); 256 ttm_tt_free_page_directory(ttm);
271 } 257 }
272 258
@@ -274,52 +260,38 @@ void ttm_tt_destroy(struct ttm_tt *ttm)
274 ttm->swap_storage) 260 ttm->swap_storage)
275 fput(ttm->swap_storage); 261 fput(ttm->swap_storage);
276 262
277 kfree(ttm); 263 ttm->swap_storage = NULL;
264 ttm->func->destroy(ttm);
278} 265}
279 266
280struct ttm_tt *ttm_tt_create(struct ttm_bo_device *bdev, unsigned long size, 267int ttm_tt_init(struct ttm_tt *ttm, struct ttm_bo_device *bdev,
281 uint32_t page_flags, struct page *dummy_read_page) 268 unsigned long size, uint32_t page_flags,
269 struct page *dummy_read_page)
282{ 270{
283 struct ttm_bo_driver *bo_driver = bdev->driver; 271 ttm->bdev = bdev;
284 struct ttm_tt *ttm;
285
286 if (!bo_driver)
287 return NULL;
288
289 ttm = kzalloc(sizeof(*ttm), GFP_KERNEL);
290 if (!ttm)
291 return NULL;
292
293 ttm->glob = bdev->glob; 272 ttm->glob = bdev->glob;
294 ttm->num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; 273 ttm->num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
295 ttm->caching_state = tt_cached; 274 ttm->caching_state = tt_cached;
296 ttm->page_flags = page_flags; 275 ttm->page_flags = page_flags;
297
298 ttm->dummy_read_page = dummy_read_page; 276 ttm->dummy_read_page = dummy_read_page;
277 ttm->state = tt_unpopulated;
299 278
300 ttm_tt_alloc_page_directory(ttm); 279 ttm_tt_alloc_page_directory(ttm);
301 if (!ttm->pages || !ttm->dma_address) { 280 if (!ttm->pages || !ttm->dma_address) {
302 ttm_tt_destroy(ttm); 281 ttm_tt_destroy(ttm);
303 printk(KERN_ERR TTM_PFX "Failed allocating page table\n"); 282 printk(KERN_ERR TTM_PFX "Failed allocating page table\n");
304 return NULL; 283 return -ENOMEM;
305 }
306 ttm->be = bo_driver->create_ttm_backend_entry(bdev);
307 if (!ttm->be) {
308 ttm_tt_destroy(ttm);
309 printk(KERN_ERR TTM_PFX "Failed creating ttm backend entry\n");
310 return NULL;
311 } 284 }
312 ttm->state = tt_unpopulated; 285 return 0;
313 return ttm;
314} 286}
287EXPORT_SYMBOL(ttm_tt_init);
315 288
316void ttm_tt_unbind(struct ttm_tt *ttm) 289void ttm_tt_unbind(struct ttm_tt *ttm)
317{ 290{
318 int ret; 291 int ret;
319 struct ttm_backend *be = ttm->be;
320 292
321 if (ttm->state == tt_bound) { 293 if (ttm->state == tt_bound) {
322 ret = be->func->unbind(be); 294 ret = ttm->func->unbind(ttm);
323 BUG_ON(ret); 295 BUG_ON(ret);
324 ttm->state = tt_unbound; 296 ttm->state = tt_unbound;
325 } 297 }
@@ -328,7 +300,6 @@ void ttm_tt_unbind(struct ttm_tt *ttm)
328int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem) 300int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem)
329{ 301{
330 int ret = 0; 302 int ret = 0;
331 struct ttm_backend *be;
332 303
333 if (!ttm) 304 if (!ttm)
334 return -EINVAL; 305 return -EINVAL;
@@ -336,13 +307,11 @@ int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem)
336 if (ttm->state == tt_bound) 307 if (ttm->state == tt_bound)
337 return 0; 308 return 0;
338 309
339 be = ttm->be;
340
341 ret = ttm_tt_populate(ttm); 310 ret = ttm_tt_populate(ttm);
342 if (ret) 311 if (ret)
343 return ret; 312 return ret;
344 313
345 ret = be->func->bind(be, bo_mem); 314 ret = ttm->func->bind(ttm, bo_mem);
346 if (unlikely(ret != 0)) 315 if (unlikely(ret != 0))
347 return ret; 316 return ret;
348 317