diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_gem.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_gem.c | 103 |
1 files changed, 73 insertions, 30 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index d1e595d91723..aa1ca2dea42f 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
@@ -32,21 +32,18 @@ | |||
32 | 32 | ||
33 | int radeon_gem_object_init(struct drm_gem_object *obj) | 33 | int radeon_gem_object_init(struct drm_gem_object *obj) |
34 | { | 34 | { |
35 | /* we do nothings here */ | 35 | BUG(); |
36 | |||
36 | return 0; | 37 | return 0; |
37 | } | 38 | } |
38 | 39 | ||
39 | void radeon_gem_object_free(struct drm_gem_object *gobj) | 40 | void radeon_gem_object_free(struct drm_gem_object *gobj) |
40 | { | 41 | { |
41 | struct radeon_bo *robj = gobj->driver_private; | 42 | struct radeon_bo *robj = gem_to_radeon_bo(gobj); |
42 | 43 | ||
43 | gobj->driver_private = NULL; | ||
44 | if (robj) { | 44 | if (robj) { |
45 | radeon_bo_unref(&robj); | 45 | radeon_bo_unref(&robj); |
46 | } | 46 | } |
47 | |||
48 | drm_gem_object_release(gobj); | ||
49 | kfree(gobj); | ||
50 | } | 47 | } |
51 | 48 | ||
52 | int radeon_gem_object_create(struct radeon_device *rdev, int size, | 49 | int radeon_gem_object_create(struct radeon_device *rdev, int size, |
@@ -54,36 +51,34 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size, | |||
54 | bool discardable, bool kernel, | 51 | bool discardable, bool kernel, |
55 | struct drm_gem_object **obj) | 52 | struct drm_gem_object **obj) |
56 | { | 53 | { |
57 | struct drm_gem_object *gobj; | ||
58 | struct radeon_bo *robj; | 54 | struct radeon_bo *robj; |
59 | int r; | 55 | int r; |
60 | 56 | ||
61 | *obj = NULL; | 57 | *obj = NULL; |
62 | gobj = drm_gem_object_alloc(rdev->ddev, size); | ||
63 | if (!gobj) { | ||
64 | return -ENOMEM; | ||
65 | } | ||
66 | /* At least align on page size */ | 58 | /* At least align on page size */ |
67 | if (alignment < PAGE_SIZE) { | 59 | if (alignment < PAGE_SIZE) { |
68 | alignment = PAGE_SIZE; | 60 | alignment = PAGE_SIZE; |
69 | } | 61 | } |
70 | r = radeon_bo_create(rdev, gobj, size, kernel, initial_domain, &robj); | 62 | r = radeon_bo_create(rdev, size, alignment, kernel, initial_domain, &robj); |
71 | if (r) { | 63 | if (r) { |
72 | if (r != -ERESTARTSYS) | 64 | if (r != -ERESTARTSYS) |
73 | DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n", | 65 | DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n", |
74 | size, initial_domain, alignment, r); | 66 | size, initial_domain, alignment, r); |
75 | drm_gem_object_unreference_unlocked(gobj); | ||
76 | return r; | 67 | return r; |
77 | } | 68 | } |
78 | gobj->driver_private = robj; | 69 | *obj = &robj->gem_base; |
79 | *obj = gobj; | 70 | |
71 | mutex_lock(&rdev->gem.mutex); | ||
72 | list_add_tail(&robj->list, &rdev->gem.objects); | ||
73 | mutex_unlock(&rdev->gem.mutex); | ||
74 | |||
80 | return 0; | 75 | return 0; |
81 | } | 76 | } |
82 | 77 | ||
83 | int radeon_gem_object_pin(struct drm_gem_object *obj, uint32_t pin_domain, | 78 | int radeon_gem_object_pin(struct drm_gem_object *obj, uint32_t pin_domain, |
84 | uint64_t *gpu_addr) | 79 | uint64_t *gpu_addr) |
85 | { | 80 | { |
86 | struct radeon_bo *robj = obj->driver_private; | 81 | struct radeon_bo *robj = gem_to_radeon_bo(obj); |
87 | int r; | 82 | int r; |
88 | 83 | ||
89 | r = radeon_bo_reserve(robj, false); | 84 | r = radeon_bo_reserve(robj, false); |
@@ -96,7 +91,7 @@ int radeon_gem_object_pin(struct drm_gem_object *obj, uint32_t pin_domain, | |||
96 | 91 | ||
97 | void radeon_gem_object_unpin(struct drm_gem_object *obj) | 92 | void radeon_gem_object_unpin(struct drm_gem_object *obj) |
98 | { | 93 | { |
99 | struct radeon_bo *robj = obj->driver_private; | 94 | struct radeon_bo *robj = gem_to_radeon_bo(obj); |
100 | int r; | 95 | int r; |
101 | 96 | ||
102 | r = radeon_bo_reserve(robj, false); | 97 | r = radeon_bo_reserve(robj, false); |
@@ -114,7 +109,7 @@ int radeon_gem_set_domain(struct drm_gem_object *gobj, | |||
114 | int r; | 109 | int r; |
115 | 110 | ||
116 | /* FIXME: reeimplement */ | 111 | /* FIXME: reeimplement */ |
117 | robj = gobj->driver_private; | 112 | robj = gem_to_radeon_bo(gobj); |
118 | /* work out where to validate the buffer to */ | 113 | /* work out where to validate the buffer to */ |
119 | domain = wdomain; | 114 | domain = wdomain; |
120 | if (!domain) { | 115 | if (!domain) { |
@@ -156,9 +151,12 @@ int radeon_gem_info_ioctl(struct drm_device *dev, void *data, | |||
156 | { | 151 | { |
157 | struct radeon_device *rdev = dev->dev_private; | 152 | struct radeon_device *rdev = dev->dev_private; |
158 | struct drm_radeon_gem_info *args = data; | 153 | struct drm_radeon_gem_info *args = data; |
154 | struct ttm_mem_type_manager *man; | ||
155 | |||
156 | man = &rdev->mman.bdev.man[TTM_PL_VRAM]; | ||
159 | 157 | ||
160 | args->vram_size = rdev->mc.real_vram_size; | 158 | args->vram_size = rdev->mc.real_vram_size; |
161 | args->vram_visible = rdev->mc.real_vram_size; | 159 | args->vram_visible = (u64)man->size << PAGE_SHIFT; |
162 | if (rdev->stollen_vga_memory) | 160 | if (rdev->stollen_vga_memory) |
163 | args->vram_visible -= radeon_bo_size(rdev->stollen_vga_memory); | 161 | args->vram_visible -= radeon_bo_size(rdev->stollen_vga_memory); |
164 | args->vram_visible -= radeon_fbdev_total_size(rdev); | 162 | args->vram_visible -= radeon_fbdev_total_size(rdev); |
@@ -228,7 +226,7 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
228 | if (gobj == NULL) { | 226 | if (gobj == NULL) { |
229 | return -ENOENT; | 227 | return -ENOENT; |
230 | } | 228 | } |
231 | robj = gobj->driver_private; | 229 | robj = gem_to_radeon_bo(gobj); |
232 | 230 | ||
233 | r = radeon_gem_set_domain(gobj, args->read_domains, args->write_domain); | 231 | r = radeon_gem_set_domain(gobj, args->read_domains, args->write_domain); |
234 | 232 | ||
@@ -236,23 +234,31 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
236 | return r; | 234 | return r; |
237 | } | 235 | } |
238 | 236 | ||
239 | int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, | 237 | int radeon_mode_dumb_mmap(struct drm_file *filp, |
240 | struct drm_file *filp) | 238 | struct drm_device *dev, |
239 | uint32_t handle, uint64_t *offset_p) | ||
241 | { | 240 | { |
242 | struct drm_radeon_gem_mmap *args = data; | ||
243 | struct drm_gem_object *gobj; | 241 | struct drm_gem_object *gobj; |
244 | struct radeon_bo *robj; | 242 | struct radeon_bo *robj; |
245 | 243 | ||
246 | gobj = drm_gem_object_lookup(dev, filp, args->handle); | 244 | gobj = drm_gem_object_lookup(dev, filp, handle); |
247 | if (gobj == NULL) { | 245 | if (gobj == NULL) { |
248 | return -ENOENT; | 246 | return -ENOENT; |
249 | } | 247 | } |
250 | robj = gobj->driver_private; | 248 | robj = gem_to_radeon_bo(gobj); |
251 | args->addr_ptr = radeon_bo_mmap_offset(robj); | 249 | *offset_p = radeon_bo_mmap_offset(robj); |
252 | drm_gem_object_unreference_unlocked(gobj); | 250 | drm_gem_object_unreference_unlocked(gobj); |
253 | return 0; | 251 | return 0; |
254 | } | 252 | } |
255 | 253 | ||
254 | int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, | ||
255 | struct drm_file *filp) | ||
256 | { | ||
257 | struct drm_radeon_gem_mmap *args = data; | ||
258 | |||
259 | return radeon_mode_dumb_mmap(filp, dev, args->handle, &args->addr_ptr); | ||
260 | } | ||
261 | |||
256 | int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, | 262 | int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, |
257 | struct drm_file *filp) | 263 | struct drm_file *filp) |
258 | { | 264 | { |
@@ -266,7 +272,7 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
266 | if (gobj == NULL) { | 272 | if (gobj == NULL) { |
267 | return -ENOENT; | 273 | return -ENOENT; |
268 | } | 274 | } |
269 | robj = gobj->driver_private; | 275 | robj = gem_to_radeon_bo(gobj); |
270 | r = radeon_bo_wait(robj, &cur_placement, true); | 276 | r = radeon_bo_wait(robj, &cur_placement, true); |
271 | switch (cur_placement) { | 277 | switch (cur_placement) { |
272 | case TTM_PL_VRAM: | 278 | case TTM_PL_VRAM: |
@@ -296,7 +302,7 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, | |||
296 | if (gobj == NULL) { | 302 | if (gobj == NULL) { |
297 | return -ENOENT; | 303 | return -ENOENT; |
298 | } | 304 | } |
299 | robj = gobj->driver_private; | 305 | robj = gem_to_radeon_bo(gobj); |
300 | r = radeon_bo_wait(robj, NULL, false); | 306 | r = radeon_bo_wait(robj, NULL, false); |
301 | /* callback hw specific functions if any */ | 307 | /* callback hw specific functions if any */ |
302 | if (robj->rdev->asic->ioctl_wait_idle) | 308 | if (robj->rdev->asic->ioctl_wait_idle) |
@@ -317,7 +323,7 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data, | |||
317 | gobj = drm_gem_object_lookup(dev, filp, args->handle); | 323 | gobj = drm_gem_object_lookup(dev, filp, args->handle); |
318 | if (gobj == NULL) | 324 | if (gobj == NULL) |
319 | return -ENOENT; | 325 | return -ENOENT; |
320 | robj = gobj->driver_private; | 326 | robj = gem_to_radeon_bo(gobj); |
321 | r = radeon_bo_set_tiling_flags(robj, args->tiling_flags, args->pitch); | 327 | r = radeon_bo_set_tiling_flags(robj, args->tiling_flags, args->pitch); |
322 | drm_gem_object_unreference_unlocked(gobj); | 328 | drm_gem_object_unreference_unlocked(gobj); |
323 | return r; | 329 | return r; |
@@ -335,7 +341,7 @@ int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data, | |||
335 | gobj = drm_gem_object_lookup(dev, filp, args->handle); | 341 | gobj = drm_gem_object_lookup(dev, filp, args->handle); |
336 | if (gobj == NULL) | 342 | if (gobj == NULL) |
337 | return -ENOENT; | 343 | return -ENOENT; |
338 | rbo = gobj->driver_private; | 344 | rbo = gem_to_radeon_bo(gobj); |
339 | r = radeon_bo_reserve(rbo, false); | 345 | r = radeon_bo_reserve(rbo, false); |
340 | if (unlikely(r != 0)) | 346 | if (unlikely(r != 0)) |
341 | goto out; | 347 | goto out; |
@@ -345,3 +351,40 @@ out: | |||
345 | drm_gem_object_unreference_unlocked(gobj); | 351 | drm_gem_object_unreference_unlocked(gobj); |
346 | return r; | 352 | return r; |
347 | } | 353 | } |
354 | |||
355 | int radeon_mode_dumb_create(struct drm_file *file_priv, | ||
356 | struct drm_device *dev, | ||
357 | struct drm_mode_create_dumb *args) | ||
358 | { | ||
359 | struct radeon_device *rdev = dev->dev_private; | ||
360 | struct drm_gem_object *gobj; | ||
361 | uint32_t handle; | ||
362 | int r; | ||
363 | |||
364 | args->pitch = radeon_align_pitch(rdev, args->width, args->bpp, 0) * ((args->bpp + 1) / 8); | ||
365 | args->size = args->pitch * args->height; | ||
366 | args->size = ALIGN(args->size, PAGE_SIZE); | ||
367 | |||
368 | r = radeon_gem_object_create(rdev, args->size, 0, | ||
369 | RADEON_GEM_DOMAIN_VRAM, | ||
370 | false, ttm_bo_type_device, | ||
371 | &gobj); | ||
372 | if (r) | ||
373 | return -ENOMEM; | ||
374 | |||
375 | r = drm_gem_handle_create(file_priv, gobj, &handle); | ||
376 | /* drop reference from allocate - handle holds it now */ | ||
377 | drm_gem_object_unreference_unlocked(gobj); | ||
378 | if (r) { | ||
379 | return r; | ||
380 | } | ||
381 | args->handle = handle; | ||
382 | return 0; | ||
383 | } | ||
384 | |||
385 | int radeon_mode_dumb_destroy(struct drm_file *file_priv, | ||
386 | struct drm_device *dev, | ||
387 | uint32_t handle) | ||
388 | { | ||
389 | return drm_gem_handle_delete(file_priv, handle); | ||
390 | } | ||