diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_gem.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_gem.c | 147 |
1 files changed, 69 insertions, 78 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index d880edf254db..ef92d147d8f0 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
@@ -38,22 +38,21 @@ int radeon_gem_object_init(struct drm_gem_object *obj) | |||
38 | 38 | ||
39 | void radeon_gem_object_free(struct drm_gem_object *gobj) | 39 | void radeon_gem_object_free(struct drm_gem_object *gobj) |
40 | { | 40 | { |
41 | struct radeon_object *robj = gobj->driver_private; | 41 | struct radeon_bo *robj = gobj->driver_private; |
42 | 42 | ||
43 | gobj->driver_private = NULL; | 43 | gobj->driver_private = NULL; |
44 | if (robj) { | 44 | if (robj) { |
45 | radeon_object_unref(&robj); | 45 | radeon_bo_unref(&robj); |
46 | } | 46 | } |
47 | } | 47 | } |
48 | 48 | ||
49 | int radeon_gem_object_create(struct radeon_device *rdev, int size, | 49 | int radeon_gem_object_create(struct radeon_device *rdev, int size, |
50 | int alignment, int initial_domain, | 50 | int alignment, int initial_domain, |
51 | bool discardable, bool kernel, | 51 | bool discardable, bool kernel, |
52 | bool interruptible, | 52 | struct drm_gem_object **obj) |
53 | struct drm_gem_object **obj) | ||
54 | { | 53 | { |
55 | struct drm_gem_object *gobj; | 54 | struct drm_gem_object *gobj; |
56 | struct radeon_object *robj; | 55 | struct radeon_bo *robj; |
57 | int r; | 56 | int r; |
58 | 57 | ||
59 | *obj = NULL; | 58 | *obj = NULL; |
@@ -65,14 +64,12 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size, | |||
65 | if (alignment < PAGE_SIZE) { | 64 | if (alignment < PAGE_SIZE) { |
66 | alignment = PAGE_SIZE; | 65 | alignment = PAGE_SIZE; |
67 | } | 66 | } |
68 | r = radeon_object_create(rdev, gobj, size, kernel, initial_domain, | 67 | r = radeon_bo_create(rdev, gobj, size, kernel, initial_domain, &robj); |
69 | interruptible, &robj); | ||
70 | if (r) { | 68 | if (r) { |
71 | DRM_ERROR("Failed to allocate GEM object (%d, %d, %u)\n", | 69 | if (r != -ERESTARTSYS) |
72 | size, initial_domain, alignment); | 70 | DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n", |
73 | mutex_lock(&rdev->ddev->struct_mutex); | 71 | size, initial_domain, alignment, r); |
74 | drm_gem_object_unreference(gobj); | 72 | drm_gem_object_unreference_unlocked(gobj); |
75 | mutex_unlock(&rdev->ddev->struct_mutex); | ||
76 | return r; | 73 | return r; |
77 | } | 74 | } |
78 | gobj->driver_private = robj; | 75 | gobj->driver_private = robj; |
@@ -83,33 +80,33 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size, | |||
83 | int radeon_gem_object_pin(struct drm_gem_object *obj, uint32_t pin_domain, | 80 | int radeon_gem_object_pin(struct drm_gem_object *obj, uint32_t pin_domain, |
84 | uint64_t *gpu_addr) | 81 | uint64_t *gpu_addr) |
85 | { | 82 | { |
86 | struct radeon_object *robj = obj->driver_private; | 83 | struct radeon_bo *robj = obj->driver_private; |
87 | uint32_t flags; | 84 | int r; |
88 | 85 | ||
89 | switch (pin_domain) { | 86 | r = radeon_bo_reserve(robj, false); |
90 | case RADEON_GEM_DOMAIN_VRAM: | 87 | if (unlikely(r != 0)) |
91 | flags = TTM_PL_FLAG_VRAM; | 88 | return r; |
92 | break; | 89 | r = radeon_bo_pin(robj, pin_domain, gpu_addr); |
93 | case RADEON_GEM_DOMAIN_GTT: | 90 | radeon_bo_unreserve(robj); |
94 | flags = TTM_PL_FLAG_TT; | 91 | return r; |
95 | break; | ||
96 | default: | ||
97 | flags = TTM_PL_FLAG_SYSTEM; | ||
98 | break; | ||
99 | } | ||
100 | return radeon_object_pin(robj, flags, gpu_addr); | ||
101 | } | 92 | } |
102 | 93 | ||
103 | void radeon_gem_object_unpin(struct drm_gem_object *obj) | 94 | void radeon_gem_object_unpin(struct drm_gem_object *obj) |
104 | { | 95 | { |
105 | struct radeon_object *robj = obj->driver_private; | 96 | struct radeon_bo *robj = obj->driver_private; |
106 | radeon_object_unpin(robj); | 97 | int r; |
98 | |||
99 | r = radeon_bo_reserve(robj, false); | ||
100 | if (likely(r == 0)) { | ||
101 | radeon_bo_unpin(robj); | ||
102 | radeon_bo_unreserve(robj); | ||
103 | } | ||
107 | } | 104 | } |
108 | 105 | ||
109 | int radeon_gem_set_domain(struct drm_gem_object *gobj, | 106 | int radeon_gem_set_domain(struct drm_gem_object *gobj, |
110 | uint32_t rdomain, uint32_t wdomain) | 107 | uint32_t rdomain, uint32_t wdomain) |
111 | { | 108 | { |
112 | struct radeon_object *robj; | 109 | struct radeon_bo *robj; |
113 | uint32_t domain; | 110 | uint32_t domain; |
114 | int r; | 111 | int r; |
115 | 112 | ||
@@ -127,7 +124,7 @@ int radeon_gem_set_domain(struct drm_gem_object *gobj, | |||
127 | } | 124 | } |
128 | if (domain == RADEON_GEM_DOMAIN_CPU) { | 125 | if (domain == RADEON_GEM_DOMAIN_CPU) { |
129 | /* Asking for cpu access wait for object idle */ | 126 | /* Asking for cpu access wait for object idle */ |
130 | r = radeon_object_wait(robj); | 127 | r = radeon_bo_wait(robj, NULL, false); |
131 | if (r) { | 128 | if (r) { |
132 | printk(KERN_ERR "Failed to wait for object !\n"); | 129 | printk(KERN_ERR "Failed to wait for object !\n"); |
133 | return r; | 130 | return r; |
@@ -144,7 +141,7 @@ int radeon_gem_init(struct radeon_device *rdev) | |||
144 | 141 | ||
145 | void radeon_gem_fini(struct radeon_device *rdev) | 142 | void radeon_gem_fini(struct radeon_device *rdev) |
146 | { | 143 | { |
147 | radeon_object_force_delete(rdev); | 144 | radeon_bo_force_delete(rdev); |
148 | } | 145 | } |
149 | 146 | ||
150 | 147 | ||
@@ -158,9 +155,13 @@ int radeon_gem_info_ioctl(struct drm_device *dev, void *data, | |||
158 | struct drm_radeon_gem_info *args = data; | 155 | struct drm_radeon_gem_info *args = data; |
159 | 156 | ||
160 | args->vram_size = rdev->mc.real_vram_size; | 157 | args->vram_size = rdev->mc.real_vram_size; |
161 | /* FIXME: report somethings that makes sense */ | 158 | args->vram_visible = rdev->mc.real_vram_size; |
162 | args->vram_visible = rdev->mc.real_vram_size - (4 * 1024 * 1024); | 159 | if (rdev->stollen_vga_memory) |
163 | args->gart_size = rdev->mc.gtt_size; | 160 | args->vram_visible -= radeon_bo_size(rdev->stollen_vga_memory); |
161 | if (rdev->fbdev_rbo) | ||
162 | args->vram_visible -= radeon_bo_size(rdev->fbdev_rbo); | ||
163 | args->gart_size = rdev->mc.gtt_size - rdev->cp.ring_size - 4096 - | ||
164 | RADEON_IB_POOL_SIZE*64*1024; | ||
164 | return 0; | 165 | return 0; |
165 | } | 166 | } |
166 | 167 | ||
@@ -192,21 +193,17 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data, | |||
192 | /* create a gem object to contain this object in */ | 193 | /* create a gem object to contain this object in */ |
193 | args->size = roundup(args->size, PAGE_SIZE); | 194 | args->size = roundup(args->size, PAGE_SIZE); |
194 | r = radeon_gem_object_create(rdev, args->size, args->alignment, | 195 | r = radeon_gem_object_create(rdev, args->size, args->alignment, |
195 | args->initial_domain, false, | 196 | args->initial_domain, false, |
196 | false, true, &gobj); | 197 | false, &gobj); |
197 | if (r) { | 198 | if (r) { |
198 | return r; | 199 | return r; |
199 | } | 200 | } |
200 | r = drm_gem_handle_create(filp, gobj, &handle); | 201 | r = drm_gem_handle_create(filp, gobj, &handle); |
201 | if (r) { | 202 | if (r) { |
202 | mutex_lock(&dev->struct_mutex); | 203 | drm_gem_object_unreference_unlocked(gobj); |
203 | drm_gem_object_unreference(gobj); | ||
204 | mutex_unlock(&dev->struct_mutex); | ||
205 | return r; | 204 | return r; |
206 | } | 205 | } |
207 | mutex_lock(&dev->struct_mutex); | 206 | drm_gem_object_handle_unreference_unlocked(gobj); |
208 | drm_gem_object_handle_unreference(gobj); | ||
209 | mutex_unlock(&dev->struct_mutex); | ||
210 | args->handle = handle; | 207 | args->handle = handle; |
211 | return 0; | 208 | return 0; |
212 | } | 209 | } |
@@ -218,7 +215,7 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
218 | * just validate the BO into a certain domain */ | 215 | * just validate the BO into a certain domain */ |
219 | struct drm_radeon_gem_set_domain *args = data; | 216 | struct drm_radeon_gem_set_domain *args = data; |
220 | struct drm_gem_object *gobj; | 217 | struct drm_gem_object *gobj; |
221 | struct radeon_object *robj; | 218 | struct radeon_bo *robj; |
222 | int r; | 219 | int r; |
223 | 220 | ||
224 | /* for now if someone requests domain CPU - | 221 | /* for now if someone requests domain CPU - |
@@ -233,9 +230,7 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
233 | 230 | ||
234 | 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); |
235 | 232 | ||
236 | mutex_lock(&dev->struct_mutex); | 233 | drm_gem_object_unreference_unlocked(gobj); |
237 | drm_gem_object_unreference(gobj); | ||
238 | mutex_unlock(&dev->struct_mutex); | ||
239 | return r; | 234 | return r; |
240 | } | 235 | } |
241 | 236 | ||
@@ -244,19 +239,16 @@ int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, | |||
244 | { | 239 | { |
245 | struct drm_radeon_gem_mmap *args = data; | 240 | struct drm_radeon_gem_mmap *args = data; |
246 | struct drm_gem_object *gobj; | 241 | struct drm_gem_object *gobj; |
247 | struct radeon_object *robj; | 242 | struct radeon_bo *robj; |
248 | int r; | ||
249 | 243 | ||
250 | gobj = drm_gem_object_lookup(dev, filp, args->handle); | 244 | gobj = drm_gem_object_lookup(dev, filp, args->handle); |
251 | if (gobj == NULL) { | 245 | if (gobj == NULL) { |
252 | return -EINVAL; | 246 | return -EINVAL; |
253 | } | 247 | } |
254 | robj = gobj->driver_private; | 248 | robj = gobj->driver_private; |
255 | r = radeon_object_mmap(robj, &args->addr_ptr); | 249 | args->addr_ptr = radeon_bo_mmap_offset(robj); |
256 | mutex_lock(&dev->struct_mutex); | 250 | drm_gem_object_unreference_unlocked(gobj); |
257 | drm_gem_object_unreference(gobj); | 251 | return 0; |
258 | mutex_unlock(&dev->struct_mutex); | ||
259 | return r; | ||
260 | } | 252 | } |
261 | 253 | ||
262 | int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, | 254 | int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, |
@@ -264,16 +256,16 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
264 | { | 256 | { |
265 | struct drm_radeon_gem_busy *args = data; | 257 | struct drm_radeon_gem_busy *args = data; |
266 | struct drm_gem_object *gobj; | 258 | struct drm_gem_object *gobj; |
267 | struct radeon_object *robj; | 259 | struct radeon_bo *robj; |
268 | int r; | 260 | int r; |
269 | uint32_t cur_placement; | 261 | uint32_t cur_placement = 0; |
270 | 262 | ||
271 | gobj = drm_gem_object_lookup(dev, filp, args->handle); | 263 | gobj = drm_gem_object_lookup(dev, filp, args->handle); |
272 | if (gobj == NULL) { | 264 | if (gobj == NULL) { |
273 | return -EINVAL; | 265 | return -EINVAL; |
274 | } | 266 | } |
275 | robj = gobj->driver_private; | 267 | robj = gobj->driver_private; |
276 | r = radeon_object_busy_domain(robj, &cur_placement); | 268 | r = radeon_bo_wait(robj, &cur_placement, true); |
277 | switch (cur_placement) { | 269 | switch (cur_placement) { |
278 | case TTM_PL_VRAM: | 270 | case TTM_PL_VRAM: |
279 | args->domain = RADEON_GEM_DOMAIN_VRAM; | 271 | args->domain = RADEON_GEM_DOMAIN_VRAM; |
@@ -286,9 +278,7 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
286 | default: | 278 | default: |
287 | break; | 279 | break; |
288 | } | 280 | } |
289 | mutex_lock(&dev->struct_mutex); | 281 | drm_gem_object_unreference_unlocked(gobj); |
290 | drm_gem_object_unreference(gobj); | ||
291 | mutex_unlock(&dev->struct_mutex); | ||
292 | return r; | 282 | return r; |
293 | } | 283 | } |
294 | 284 | ||
@@ -297,7 +287,7 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, | |||
297 | { | 287 | { |
298 | struct drm_radeon_gem_wait_idle *args = data; | 288 | struct drm_radeon_gem_wait_idle *args = data; |
299 | struct drm_gem_object *gobj; | 289 | struct drm_gem_object *gobj; |
300 | struct radeon_object *robj; | 290 | struct radeon_bo *robj; |
301 | int r; | 291 | int r; |
302 | 292 | ||
303 | gobj = drm_gem_object_lookup(dev, filp, args->handle); | 293 | gobj = drm_gem_object_lookup(dev, filp, args->handle); |
@@ -305,10 +295,11 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, | |||
305 | return -EINVAL; | 295 | return -EINVAL; |
306 | } | 296 | } |
307 | robj = gobj->driver_private; | 297 | robj = gobj->driver_private; |
308 | r = radeon_object_wait(robj); | 298 | r = radeon_bo_wait(robj, NULL, false); |
309 | mutex_lock(&dev->struct_mutex); | 299 | /* callback hw specific functions if any */ |
310 | drm_gem_object_unreference(gobj); | 300 | if (robj->rdev->asic->ioctl_wait_idle) |
311 | mutex_unlock(&dev->struct_mutex); | 301 | robj->rdev->asic->ioctl_wait_idle(robj->rdev, robj); |
302 | drm_gem_object_unreference_unlocked(gobj); | ||
312 | return r; | 303 | return r; |
313 | } | 304 | } |
314 | 305 | ||
@@ -317,7 +308,7 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data, | |||
317 | { | 308 | { |
318 | struct drm_radeon_gem_set_tiling *args = data; | 309 | struct drm_radeon_gem_set_tiling *args = data; |
319 | struct drm_gem_object *gobj; | 310 | struct drm_gem_object *gobj; |
320 | struct radeon_object *robj; | 311 | struct radeon_bo *robj; |
321 | int r = 0; | 312 | int r = 0; |
322 | 313 | ||
323 | DRM_DEBUG("%d \n", args->handle); | 314 | DRM_DEBUG("%d \n", args->handle); |
@@ -325,10 +316,8 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data, | |||
325 | if (gobj == NULL) | 316 | if (gobj == NULL) |
326 | return -EINVAL; | 317 | return -EINVAL; |
327 | robj = gobj->driver_private; | 318 | robj = gobj->driver_private; |
328 | radeon_object_set_tiling_flags(robj, args->tiling_flags, args->pitch); | 319 | r = radeon_bo_set_tiling_flags(robj, args->tiling_flags, args->pitch); |
329 | mutex_lock(&dev->struct_mutex); | 320 | drm_gem_object_unreference_unlocked(gobj); |
330 | drm_gem_object_unreference(gobj); | ||
331 | mutex_unlock(&dev->struct_mutex); | ||
332 | return r; | 321 | return r; |
333 | } | 322 | } |
334 | 323 | ||
@@ -337,18 +326,20 @@ int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data, | |||
337 | { | 326 | { |
338 | struct drm_radeon_gem_get_tiling *args = data; | 327 | struct drm_radeon_gem_get_tiling *args = data; |
339 | struct drm_gem_object *gobj; | 328 | struct drm_gem_object *gobj; |
340 | struct radeon_object *robj; | 329 | struct radeon_bo *rbo; |
341 | int r = 0; | 330 | int r = 0; |
342 | 331 | ||
343 | DRM_DEBUG("\n"); | 332 | DRM_DEBUG("\n"); |
344 | gobj = drm_gem_object_lookup(dev, filp, args->handle); | 333 | gobj = drm_gem_object_lookup(dev, filp, args->handle); |
345 | if (gobj == NULL) | 334 | if (gobj == NULL) |
346 | return -EINVAL; | 335 | return -EINVAL; |
347 | robj = gobj->driver_private; | 336 | rbo = gobj->driver_private; |
348 | radeon_object_get_tiling_flags(robj, &args->tiling_flags, | 337 | r = radeon_bo_reserve(rbo, false); |
349 | &args->pitch); | 338 | if (unlikely(r != 0)) |
350 | mutex_lock(&dev->struct_mutex); | 339 | goto out; |
351 | drm_gem_object_unreference(gobj); | 340 | radeon_bo_get_tiling_flags(rbo, &args->tiling_flags, &args->pitch); |
352 | mutex_unlock(&dev->struct_mutex); | 341 | radeon_bo_unreserve(rbo); |
342 | out: | ||
343 | drm_gem_object_unreference_unlocked(gobj); | ||
353 | return r; | 344 | return r; |
354 | } | 345 | } |