diff options
author | Dave Airlie <airlied@redhat.com> | 2011-02-06 21:16:14 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-02-06 21:16:14 -0500 |
commit | ff72145badb834e8051719ea66e024784d000cb4 (patch) | |
tree | 39dc5fc512e3e0836713de9defb91ea8b4033aa2 /drivers | |
parent | 1f692a14cbfbeb11f9a9c16f25c8ecb8ab50d3d5 (diff) |
drm: dumb scanout create/mmap for intel/radeon (v3)
This is just an idea that might or might not be a good idea,
it basically adds two ioctls to create a dumb and map a dumb buffer
suitable for scanout. The handle can be passed to the KMS ioctls to create
a framebuffer.
It looks to me like it would be useful in the following cases:
a) in development drivers - we can always provide a shadowfb fallback.
b) libkms users - we can clean up libkms a lot and avoid linking
to libdrm_*.
c) plymouth via libkms is a lot easier.
Userspace bits would be just calls + mmaps. We could probably
mark these handles somehow as not being suitable for acceleartion
so as top stop people who are dumber than dumb.
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 33 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_drv.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_gem.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 103 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_drv.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_fb.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_gem.c | 53 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_mode.h | 1 |
11 files changed, 194 insertions, 38 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 654faa803dcb..4c95b5fd9df3 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -2694,3 +2694,36 @@ void drm_mode_config_reset(struct drm_device *dev) | |||
2694 | connector->funcs->reset(connector); | 2694 | connector->funcs->reset(connector); |
2695 | } | 2695 | } |
2696 | EXPORT_SYMBOL(drm_mode_config_reset); | 2696 | EXPORT_SYMBOL(drm_mode_config_reset); |
2697 | |||
2698 | int drm_mode_create_dumb_ioctl(struct drm_device *dev, | ||
2699 | void *data, struct drm_file *file_priv) | ||
2700 | { | ||
2701 | struct drm_mode_create_dumb *args = data; | ||
2702 | |||
2703 | if (!dev->driver->dumb_create) | ||
2704 | return -ENOSYS; | ||
2705 | return dev->driver->dumb_create(file_priv, dev, args); | ||
2706 | } | ||
2707 | |||
2708 | int drm_mode_mmap_dumb_ioctl(struct drm_device *dev, | ||
2709 | void *data, struct drm_file *file_priv) | ||
2710 | { | ||
2711 | struct drm_mode_map_dumb *args = data; | ||
2712 | |||
2713 | /* call driver ioctl to get mmap offset */ | ||
2714 | if (!dev->driver->dumb_map_offset) | ||
2715 | return -ENOSYS; | ||
2716 | |||
2717 | return dev->driver->dumb_map_offset(file_priv, dev, args->handle, &args->offset); | ||
2718 | } | ||
2719 | |||
2720 | int drm_mode_destroy_dumb_ioctl(struct drm_device *dev, | ||
2721 | void *data, struct drm_file *file_priv) | ||
2722 | { | ||
2723 | struct drm_mode_destroy_dumb *args = data; | ||
2724 | |||
2725 | if (!dev->driver->dumb_destroy) | ||
2726 | return -ENOSYS; | ||
2727 | |||
2728 | return dev->driver->dumb_destroy(file_priv, dev, args->handle); | ||
2729 | } | ||
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 271835a71570..3e991980cee2 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -150,7 +150,10 @@ static struct drm_ioctl_desc drm_ioctls[] = { | |||
150 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 150 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
151 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 151 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
152 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 152 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
153 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED) | 153 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
154 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
155 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | ||
156 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED) | ||
154 | }; | 157 | }; |
155 | 158 | ||
156 | #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) | 159 | #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) |
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index ea1c4b019ebf..aa8df2534819 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
@@ -181,7 +181,7 @@ EXPORT_SYMBOL(drm_gem_object_alloc); | |||
181 | /** | 181 | /** |
182 | * Removes the mapping from handle to filp for this object. | 182 | * Removes the mapping from handle to filp for this object. |
183 | */ | 183 | */ |
184 | static int | 184 | int |
185 | drm_gem_handle_delete(struct drm_file *filp, u32 handle) | 185 | drm_gem_handle_delete(struct drm_file *filp, u32 handle) |
186 | { | 186 | { |
187 | struct drm_device *dev; | 187 | struct drm_device *dev; |
@@ -214,6 +214,7 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle) | |||
214 | 214 | ||
215 | return 0; | 215 | return 0; |
216 | } | 216 | } |
217 | EXPORT_SYMBOL(drm_gem_handle_delete); | ||
217 | 218 | ||
218 | /** | 219 | /** |
219 | * Create a handle for this object. This adds a handle reference | 220 | * Create a handle for this object. This adds a handle reference |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index cfb56d0ff367..17fde2f27418 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -700,6 +700,9 @@ static struct drm_driver driver = { | |||
700 | .gem_init_object = i915_gem_init_object, | 700 | .gem_init_object = i915_gem_init_object, |
701 | .gem_free_object = i915_gem_free_object, | 701 | .gem_free_object = i915_gem_free_object, |
702 | .gem_vm_ops = &i915_gem_vm_ops, | 702 | .gem_vm_ops = &i915_gem_vm_ops, |
703 | .dumb_create = i915_gem_dumb_create, | ||
704 | .dumb_map_offset = i915_gem_mmap_gtt, | ||
705 | .dumb_destroy = i915_gem_dumb_destroy, | ||
703 | .ioctls = i915_ioctls, | 706 | .ioctls = i915_ioctls, |
704 | .fops = { | 707 | .fops = { |
705 | .owner = THIS_MODULE, | 708 | .owner = THIS_MODULE, |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a0149c619cdd..a78197d43ce6 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -1114,6 +1114,13 @@ void i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, | |||
1114 | struct intel_ring_buffer *ring, | 1114 | struct intel_ring_buffer *ring, |
1115 | u32 seqno); | 1115 | u32 seqno); |
1116 | 1116 | ||
1117 | int i915_gem_dumb_create(struct drm_file *file_priv, | ||
1118 | struct drm_device *dev, | ||
1119 | struct drm_mode_create_dumb *args); | ||
1120 | int i915_gem_mmap_gtt(struct drm_file *file_priv, struct drm_device *dev, | ||
1121 | uint32_t handle, uint64_t *offset); | ||
1122 | int i915_gem_dumb_destroy(struct drm_file *file_priv, struct drm_device *dev, | ||
1123 | uint32_t handle); | ||
1117 | /** | 1124 | /** |
1118 | * Returns true if seq1 is later than seq2. | 1125 | * Returns true if seq1 is later than seq2. |
1119 | */ | 1126 | */ |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index cf4f74c7c6fb..bc7f06b8fbca 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -193,22 +193,20 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, | |||
193 | return 0; | 193 | return 0; |
194 | } | 194 | } |
195 | 195 | ||
196 | /** | 196 | static int |
197 | * Creates a new mm object and returns a handle to it. | 197 | i915_gem_create(struct drm_file *file, |
198 | */ | 198 | struct drm_device *dev, |
199 | int | 199 | uint64_t size, |
200 | i915_gem_create_ioctl(struct drm_device *dev, void *data, | 200 | uint32_t *handle_p) |
201 | struct drm_file *file) | ||
202 | { | 201 | { |
203 | struct drm_i915_gem_create *args = data; | ||
204 | struct drm_i915_gem_object *obj; | 202 | struct drm_i915_gem_object *obj; |
205 | int ret; | 203 | int ret; |
206 | u32 handle; | 204 | u32 handle; |
207 | 205 | ||
208 | args->size = roundup(args->size, PAGE_SIZE); | 206 | size = roundup(size, PAGE_SIZE); |
209 | 207 | ||
210 | /* Allocate the new object */ | 208 | /* Allocate the new object */ |
211 | obj = i915_gem_alloc_object(dev, args->size); | 209 | obj = i915_gem_alloc_object(dev, size); |
212 | if (obj == NULL) | 210 | if (obj == NULL) |
213 | return -ENOMEM; | 211 | return -ENOMEM; |
214 | 212 | ||
@@ -224,10 +222,41 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, | |||
224 | drm_gem_object_unreference(&obj->base); | 222 | drm_gem_object_unreference(&obj->base); |
225 | trace_i915_gem_object_create(obj); | 223 | trace_i915_gem_object_create(obj); |
226 | 224 | ||
227 | args->handle = handle; | 225 | *handle_p = handle; |
228 | return 0; | 226 | return 0; |
229 | } | 227 | } |
230 | 228 | ||
229 | int | ||
230 | i915_gem_dumb_create(struct drm_file *file, | ||
231 | struct drm_device *dev, | ||
232 | struct drm_mode_create_dumb *args) | ||
233 | { | ||
234 | /* have to work out size/pitch and return them */ | ||
235 | args->pitch = ALIGN(args->width & ((args->bpp + 1) / 8), 64); | ||
236 | args->size = args->pitch * args->height; | ||
237 | return i915_gem_create(file, dev, | ||
238 | args->size, &args->handle); | ||
239 | } | ||
240 | |||
241 | int i915_gem_dumb_destroy(struct drm_file *file, | ||
242 | struct drm_device *dev, | ||
243 | uint32_t handle) | ||
244 | { | ||
245 | return drm_gem_handle_delete(file, handle); | ||
246 | } | ||
247 | |||
248 | /** | ||
249 | * Creates a new mm object and returns a handle to it. | ||
250 | */ | ||
251 | int | ||
252 | i915_gem_create_ioctl(struct drm_device *dev, void *data, | ||
253 | struct drm_file *file) | ||
254 | { | ||
255 | struct drm_i915_gem_create *args = data; | ||
256 | return i915_gem_create(file, dev, | ||
257 | args->size, &args->handle); | ||
258 | } | ||
259 | |||
231 | static int i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj) | 260 | static int i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj) |
232 | { | 261 | { |
233 | drm_i915_private_t *dev_priv = obj->base.dev->dev_private; | 262 | drm_i915_private_t *dev_priv = obj->base.dev->dev_private; |
@@ -1425,27 +1454,13 @@ i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj) | |||
1425 | return tile_height * obj->stride * 2; | 1454 | return tile_height * obj->stride * 2; |
1426 | } | 1455 | } |
1427 | 1456 | ||
1428 | /** | ||
1429 | * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing | ||
1430 | * @dev: DRM device | ||
1431 | * @data: GTT mapping ioctl data | ||
1432 | * @file: GEM object info | ||
1433 | * | ||
1434 | * Simply returns the fake offset to userspace so it can mmap it. | ||
1435 | * The mmap call will end up in drm_gem_mmap(), which will set things | ||
1436 | * up so we can get faults in the handler above. | ||
1437 | * | ||
1438 | * The fault handler will take care of binding the object into the GTT | ||
1439 | * (since it may have been evicted to make room for something), allocating | ||
1440 | * a fence register, and mapping the appropriate aperture address into | ||
1441 | * userspace. | ||
1442 | */ | ||
1443 | int | 1457 | int |
1444 | i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, | 1458 | i915_gem_mmap_gtt(struct drm_file *file, |
1445 | struct drm_file *file) | 1459 | struct drm_device *dev, |
1460 | uint32_t handle, | ||
1461 | uint64_t *offset) | ||
1446 | { | 1462 | { |
1447 | struct drm_i915_private *dev_priv = dev->dev_private; | 1463 | struct drm_i915_private *dev_priv = dev->dev_private; |
1448 | struct drm_i915_gem_mmap_gtt *args = data; | ||
1449 | struct drm_i915_gem_object *obj; | 1464 | struct drm_i915_gem_object *obj; |
1450 | int ret; | 1465 | int ret; |
1451 | 1466 | ||
@@ -1456,7 +1471,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, | |||
1456 | if (ret) | 1471 | if (ret) |
1457 | return ret; | 1472 | return ret; |
1458 | 1473 | ||
1459 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); | 1474 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, handle)); |
1460 | if (obj == NULL) { | 1475 | if (obj == NULL) { |
1461 | ret = -ENOENT; | 1476 | ret = -ENOENT; |
1462 | goto unlock; | 1477 | goto unlock; |
@@ -1479,7 +1494,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, | |||
1479 | goto out; | 1494 | goto out; |
1480 | } | 1495 | } |
1481 | 1496 | ||
1482 | args->offset = (u64)obj->base.map_list.hash.key << PAGE_SHIFT; | 1497 | *offset = (u64)obj->base.map_list.hash.key << PAGE_SHIFT; |
1483 | 1498 | ||
1484 | out: | 1499 | out: |
1485 | drm_gem_object_unreference(&obj->base); | 1500 | drm_gem_object_unreference(&obj->base); |
@@ -1488,6 +1503,34 @@ unlock: | |||
1488 | return ret; | 1503 | return ret; |
1489 | } | 1504 | } |
1490 | 1505 | ||
1506 | /** | ||
1507 | * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing | ||
1508 | * @dev: DRM device | ||
1509 | * @data: GTT mapping ioctl data | ||
1510 | * @file: GEM object info | ||
1511 | * | ||
1512 | * Simply returns the fake offset to userspace so it can mmap it. | ||
1513 | * The mmap call will end up in drm_gem_mmap(), which will set things | ||
1514 | * up so we can get faults in the handler above. | ||
1515 | * | ||
1516 | * The fault handler will take care of binding the object into the GTT | ||
1517 | * (since it may have been evicted to make room for something), allocating | ||
1518 | * a fence register, and mapping the appropriate aperture address into | ||
1519 | * userspace. | ||
1520 | */ | ||
1521 | int | ||
1522 | i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, | ||
1523 | struct drm_file *file) | ||
1524 | { | ||
1525 | struct drm_i915_gem_mmap_gtt *args = data; | ||
1526 | |||
1527 | if (!(dev->driver->driver_features & DRIVER_GEM)) | ||
1528 | return -ENODEV; | ||
1529 | |||
1530 | return i915_gem_mmap_gtt(file, dev, args->handle, &args->offset); | ||
1531 | } | ||
1532 | |||
1533 | |||
1491 | static int | 1534 | static int |
1492 | i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, | 1535 | i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, |
1493 | gfp_t gfpmask) | 1536 | gfp_t gfpmask) |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 56c48b67ef3d..a4605362c528 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -288,6 +288,15 @@ int radeon_gem_object_pin(struct drm_gem_object *obj, uint32_t pin_domain, | |||
288 | uint64_t *gpu_addr); | 288 | uint64_t *gpu_addr); |
289 | void radeon_gem_object_unpin(struct drm_gem_object *obj); | 289 | void radeon_gem_object_unpin(struct drm_gem_object *obj); |
290 | 290 | ||
291 | int radeon_mode_dumb_create(struct drm_file *file_priv, | ||
292 | struct drm_device *dev, | ||
293 | struct drm_mode_create_dumb *args); | ||
294 | int radeon_mode_dumb_mmap(struct drm_file *filp, | ||
295 | struct drm_device *dev, | ||
296 | uint32_t handle, uint64_t *offset_p); | ||
297 | int radeon_mode_dumb_destroy(struct drm_file *file_priv, | ||
298 | struct drm_device *dev, | ||
299 | uint32_t handle); | ||
291 | 300 | ||
292 | /* | 301 | /* |
293 | * GART structures, functions & helpers | 302 | * GART structures, functions & helpers |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 275b26a708d6..ca1b7d4c1d83 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -84,6 +84,16 @@ extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, | |||
84 | extern struct drm_ioctl_desc radeon_ioctls_kms[]; | 84 | extern struct drm_ioctl_desc radeon_ioctls_kms[]; |
85 | extern int radeon_max_kms_ioctl; | 85 | extern int radeon_max_kms_ioctl; |
86 | int radeon_mmap(struct file *filp, struct vm_area_struct *vma); | 86 | int radeon_mmap(struct file *filp, struct vm_area_struct *vma); |
87 | int radeon_mode_dumb_mmap(struct drm_file *filp, | ||
88 | struct drm_device *dev, | ||
89 | uint32_t handle, uint64_t *offset_p); | ||
90 | int radeon_mode_dumb_create(struct drm_file *file_priv, | ||
91 | struct drm_device *dev, | ||
92 | struct drm_mode_create_dumb *args); | ||
93 | int radeon_mode_dumb_destroy(struct drm_file *file_priv, | ||
94 | struct drm_device *dev, | ||
95 | uint32_t handle); | ||
96 | |||
87 | #if defined(CONFIG_DEBUG_FS) | 97 | #if defined(CONFIG_DEBUG_FS) |
88 | int radeon_debugfs_init(struct drm_minor *minor); | 98 | int radeon_debugfs_init(struct drm_minor *minor); |
89 | void radeon_debugfs_cleanup(struct drm_minor *minor); | 99 | void radeon_debugfs_cleanup(struct drm_minor *minor); |
@@ -322,6 +332,9 @@ static struct drm_driver kms_driver = { | |||
322 | .gem_init_object = radeon_gem_object_init, | 332 | .gem_init_object = radeon_gem_object_init, |
323 | .gem_free_object = radeon_gem_object_free, | 333 | .gem_free_object = radeon_gem_object_free, |
324 | .dma_ioctl = radeon_dma_ioctl_kms, | 334 | .dma_ioctl = radeon_dma_ioctl_kms, |
335 | .dumb_create = radeon_mode_dumb_create, | ||
336 | .dumb_map_offset = radeon_mode_dumb_mmap, | ||
337 | .dumb_destroy = radeon_mode_dumb_destroy, | ||
325 | .fops = { | 338 | .fops = { |
326 | .owner = THIS_MODULE, | 339 | .owner = THIS_MODULE, |
327 | .open = drm_open, | 340 | .open = drm_open, |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 66324b5bb5ba..cb968f997ce7 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -64,7 +64,7 @@ static struct fb_ops radeonfb_ops = { | |||
64 | }; | 64 | }; |
65 | 65 | ||
66 | 66 | ||
67 | static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled) | 67 | int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled) |
68 | { | 68 | { |
69 | int aligned = width; | 69 | int aligned = width; |
70 | int align_large = (ASIC_IS_AVIVO(rdev)) || tiled; | 70 | int align_large = (ASIC_IS_AVIVO(rdev)) || tiled; |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index df95eb83dac6..ede5dccdf79f 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
@@ -236,23 +236,31 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
236 | return r; | 236 | return r; |
237 | } | 237 | } |
238 | 238 | ||
239 | int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, | 239 | int radeon_mode_dumb_mmap(struct drm_file *filp, |
240 | struct drm_file *filp) | 240 | struct drm_device *dev, |
241 | uint32_t handle, uint64_t *offset_p) | ||
241 | { | 242 | { |
242 | struct drm_radeon_gem_mmap *args = data; | ||
243 | struct drm_gem_object *gobj; | 243 | struct drm_gem_object *gobj; |
244 | struct radeon_bo *robj; | 244 | struct radeon_bo *robj; |
245 | 245 | ||
246 | gobj = drm_gem_object_lookup(dev, filp, args->handle); | 246 | gobj = drm_gem_object_lookup(dev, filp, handle); |
247 | if (gobj == NULL) { | 247 | if (gobj == NULL) { |
248 | return -ENOENT; | 248 | return -ENOENT; |
249 | } | 249 | } |
250 | robj = gobj->driver_private; | 250 | robj = gobj->driver_private; |
251 | args->addr_ptr = radeon_bo_mmap_offset(robj); | 251 | *offset_p = radeon_bo_mmap_offset(robj); |
252 | drm_gem_object_unreference_unlocked(gobj); | 252 | drm_gem_object_unreference_unlocked(gobj); |
253 | return 0; | 253 | return 0; |
254 | } | 254 | } |
255 | 255 | ||
256 | int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, | ||
257 | struct drm_file *filp) | ||
258 | { | ||
259 | struct drm_radeon_gem_mmap *args = data; | ||
260 | |||
261 | return radeon_mode_dumb_mmap(filp, dev, args->handle, &args->addr_ptr); | ||
262 | } | ||
263 | |||
256 | int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, | 264 | int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, |
257 | struct drm_file *filp) | 265 | struct drm_file *filp) |
258 | { | 266 | { |
@@ -345,3 +353,38 @@ out: | |||
345 | drm_gem_object_unreference_unlocked(gobj); | 353 | drm_gem_object_unreference_unlocked(gobj); |
346 | return r; | 354 | return r; |
347 | } | 355 | } |
356 | |||
357 | int radeon_mode_dumb_create(struct drm_file *file_priv, | ||
358 | struct drm_device *dev, | ||
359 | struct drm_mode_create_dumb *args) | ||
360 | { | ||
361 | struct radeon_device *rdev = dev->dev_private; | ||
362 | struct drm_gem_object *gobj; | ||
363 | int r; | ||
364 | |||
365 | args->pitch = radeon_align_pitch(rdev, args->width, args->bpp, 0) * ((args->bpp + 1) / 8); | ||
366 | args->size = args->pitch * args->height; | ||
367 | args->size = ALIGN(args->size, PAGE_SIZE); | ||
368 | |||
369 | r = radeon_gem_object_create(rdev, args->size, 0, | ||
370 | RADEON_GEM_DOMAIN_VRAM, | ||
371 | false, ttm_bo_type_device, | ||
372 | &gobj); | ||
373 | if (r) | ||
374 | return -ENOMEM; | ||
375 | |||
376 | r = drm_gem_handle_create(file_priv, gobj, &args->handle); | ||
377 | if (r) { | ||
378 | drm_gem_object_unreference_unlocked(gobj); | ||
379 | return r; | ||
380 | } | ||
381 | drm_gem_object_handle_unreference_unlocked(gobj); | ||
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 | } | ||
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 6794cdf91f28..c3f23f6ff60e 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -675,4 +675,5 @@ void radeon_fb_output_poll_changed(struct radeon_device *rdev); | |||
675 | 675 | ||
676 | void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id); | 676 | void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id); |
677 | 677 | ||
678 | int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled); | ||
678 | #endif | 679 | #endif |