@@ -2653,3 +2653,26 @@ out:
mutex_unlock(&dev->mode_config.mutex);
return ret;
}
+
+int drm_mode_create_dumb_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv)
+{
+ struct drm_mode_create_dumb *args = data;
+
+ if (!dev->driver->dumb_create)
+ return -ENOSYS;
+
+ return dev->driver->dumb_create(file_priv, dev, args->size, &args->handle);
+}
+
+int drm_mode_mmap_dumb_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv)
+{
+ struct drm_mode_map_dumb *args = data;
+
+ /* call driver ioctl to get mmap offset */
+ if (!dev->driver->dumb_map_offset)
+ return -ENOSYS;
+
+ return dev->driver->dumb_map_offset(file_priv, dev, args->handle, &args->offset);
+}
@@ -146,7 +146,9 @@ static struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED)
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED)
};
#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
@@ -526,6 +526,8 @@ static struct drm_driver driver = {
.gem_init_object = i915_gem_init_object,
.gem_free_object = i915_gem_free_object,
.gem_vm_ops = &i915_gem_vm_ops,
+ .dumb_create = i915_gem_dumb_create,
+ .dumb_map_offset = i915_gem_mmap_gtt,
.ioctls = i915_ioctls,
.fops = {
.owner = THIS_MODULE,
@@ -930,6 +930,11 @@ void i915_gem_object_flush_write_domain(struct drm_gem_object *obj);
void i915_gem_shrinker_init(void);
void i915_gem_shrinker_exit(void);
+int i915_gem_dumb_create(struct drm_file *file_priv,
+ struct drm_device *dev, uint64_t size,
+ uint32_t *handle_p);
+int i915_gem_mmap_gtt(struct drm_file *file_priv, struct drm_device *dev,
+ uint32_t handle, uint64_t *offset);
/* i915_gem_tiling.c */
void i915_gem_detect_bit_6_swizzle(struct drm_device *dev);
@@ -107,23 +107,23 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
return 0;
}
-
/**
* Creates a new mm object and returns a handle to it.
*/
int
-i915_gem_create_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
+i915_gem_dumb_create(struct drm_file *file_priv,
+ struct drm_device *dev, uint64_t size,
+ uint32_t *handle_p)
+
{
- struct drm_i915_gem_create *args = data;
struct drm_gem_object *obj;
int ret;
u32 handle;
- args->size = roundup(args->size, PAGE_SIZE);
+ size = roundup(size, PAGE_SIZE);
/* Allocate the new object */
- obj = drm_gem_object_alloc(dev, args->size);
+ obj = drm_gem_object_alloc(dev, size);
if (obj == NULL)
return -ENOMEM;
@@ -133,10 +133,21 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
if (ret)
return ret;
- args->handle = handle;
+ *handle_p = handle;
return 0;
}
+/**
+ * Creates a new mm object and returns a handle to it.
+ */
+int
+i915_gem_create_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_i915_gem_create *args = data;
+ return i915_gem_dumb_create(file_priv, dev,
+ args->size, &args->handle);
+}
static inline int
fast_shmem_read(struct page **pages,
@@ -1371,35 +1382,18 @@ i915_gem_get_gtt_alignment(struct drm_gem_object *obj)
return i;
}
-/**
- * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
- * @dev: DRM device
- * @data: GTT mapping ioctl data
- * @file_priv: GEM object info
- *
- * Simply returns the fake offset to userspace so it can mmap it.
- * The mmap call will end up in drm_gem_mmap(), which will set things
- * up so we can get faults in the handler above.
- *
- * The fault handler will take care of binding the object into the GTT
- * (since it may have been evicted to make room for something), allocating
- * a fence register, and mapping the appropriate aperture address into
- * userspace.
- */
int
-i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
+i915_gem_mmap_gtt(struct drm_file *file_priv,
+ struct drm_device *dev,
+ uint32_t handle,
+ uint64_t *offset)
{
- struct drm_i915_gem_mmap_gtt *args = data;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_gem_object *obj;
struct drm_i915_gem_object *obj_priv;
int ret;
- if (!(dev->driver->driver_features & DRIVER_GEM))
- return -ENODEV;
-
- obj = drm_gem_object_lookup(dev, file_priv, args->handle);
+ obj = drm_gem_object_lookup(dev, file_priv, handle);
if (obj == NULL)
return -EBADF;
@@ -1424,7 +1418,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
}
}
- args->offset = obj_priv->mmap_offset;
+ *offset = obj_priv->mmap_offset;
/*
* Pull it into the GTT so that we have a page list (makes the
@@ -1439,13 +1433,39 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
}
list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list);
}
-
+
drm_gem_object_unreference(obj);
mutex_unlock(&dev->struct_mutex);
-
return 0;
}
+/**
+ * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
+ * @dev: DRM device
+ * @data: GTT mapping ioctl data
+ * @file_priv: GEM object info
+ *
+ * Simply returns the fake offset to userspace so it can mmap it.
+ * The mmap call will end up in drm_gem_mmap(), which will set things
+ * up so we can get faults in the handler above.
+ *
+ * The fault handler will take care of binding the object into the GTT
+ * (since it may have been evicted to make room for something), allocating
+ * a fence register, and mapping the appropriate aperture address into
+ * userspace.
+ */
+int
+i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_i915_gem_mmap_gtt *args = data;
+
+ if (!(dev->driver->driver_features & DRIVER_GEM))
+ return -ENODEV;
+
+ return i915_gem_mmap_gtt(file_priv, dev, args->handle, &args->offset);
+}
+
void
i915_gem_object_put_pages(struct drm_gem_object *obj)
{
@@ -5165,3 +5185,5 @@ i915_gem_shrinker_exit(void)
{
unregister_shrinker(&shrinker);
}
+
+
@@ -71,6 +71,12 @@ void radeon_gem_object_free(struct drm_gem_object *obj);
extern struct drm_ioctl_desc radeon_ioctls_kms[];
extern int radeon_max_kms_ioctl;
int radeon_mmap(struct file *filp, struct vm_area_struct *vma);
+int radeon_mode_dumb_mmap(struct drm_file *filp,
+ struct drm_device *dev,
+ uint32_t handle, uint64_t *offset_p);
+int radeon_mode_dumb_create(struct drm_file *file_priv,
+ struct drm_device *dev, uint64_t size, uint32_t *handle_p);
+
#if defined(CONFIG_DEBUG_FS)
int radeon_debugfs_init(struct drm_minor *minor);
void radeon_debugfs_cleanup(struct drm_minor *minor);
@@ -286,6 +292,8 @@ static struct drm_driver kms_driver = {
.gem_init_object = radeon_gem_object_init,
.gem_free_object = radeon_gem_object_free,
.dma_ioctl = radeon_dma_ioctl_kms,
+ .dumb_create = radeon_mode_dumb_create,
+ .dumb_map_offset = radeon_mode_dumb_mmap,
.fops = {
.owner = THIS_MODULE,
.open = drm_open,
@@ -234,23 +234,31 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data,
return r;
}
-int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data,
- struct drm_file *filp)
+int radeon_mode_dumb_mmap(struct drm_file *filp,
+ struct drm_device *dev,
+ uint32_t handle, uint64_t *offset_p)
{
- struct drm_radeon_gem_mmap *args = data;
struct drm_gem_object *gobj;
struct radeon_bo *robj;
-
- gobj = drm_gem_object_lookup(dev, filp, args->handle);
+
+ gobj = drm_gem_object_lookup(dev, filp, handle);
if (gobj == NULL) {
return -EINVAL;
}
robj = gobj->driver_private;
- args->addr_ptr = radeon_bo_mmap_offset(robj);
+ *offset_p = radeon_bo_mmap_offset(robj);
drm_gem_object_unreference_unlocked(gobj);
return 0;
}
+int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *filp)
+{
+ struct drm_radeon_gem_mmap *args = data;
+
+ return radeon_mode_dumb_mmap(filp, dev, args->handle, &args->addr_ptr);
+}
+
int radeon_gem_busy_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp)
{
@@ -343,3 +351,31 @@ out:
drm_gem_object_unreference_unlocked(gobj);
return r;
}
+
+int radeon_mode_dumb_create(struct drm_file *file_priv,
+ struct drm_device *dev, uint64_t size, uint32_t *handle_p)
+{
+ struct radeon_device *rdev = dev->dev_private;
+ struct drm_gem_object *gobj;
+ int r;
+ uint32_t handle;
+
+ size = ALIGN(size, PAGE_SIZE);
+
+ r = radeon_gem_object_create(rdev, size, 0,
+ RADEON_GEM_DOMAIN_VRAM,
+ false, ttm_bo_type_device,
+ &gobj);
+ if (r)
+ return -ENOMEM;
+
+ r = drm_gem_handle_create(file_priv, gobj, &handle);
+ if (r) {
+ drm_gem_object_unreference_unlocked(gobj);
+ return r;
+ }
+ drm_gem_object_handle_unreference_unlocked(gobj);
+ *handle_p = handle;
+ return 0;
+}
+
@@ -575,4 +575,6 @@ void radeon_legacy_tv_adjust_pll2(struct drm_encoder *encoder,
void radeon_legacy_tv_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
+
+
#endif
@@ -699,6 +699,9 @@ struct drm_gem_open {
#define DRM_IOCTL_MODE_PAGE_FLIP DRM_IOWR(0xB0, struct drm_mode_crtc_page_flip)
#define DRM_IOCTL_MODE_DIRTYFB DRM_IOWR(0xB1, struct drm_mode_fb_dirty_cmd)
+#define DRM_IOCTL_MODE_CREATE_DUMB DRM_IOWR(0xB0, struct drm_mode_create_dumb)
+#define DRM_IOCTL_MODE_MAP_DUMB DRM_IOWR(0xB1, struct drm_mode_map_dumb)
+
/**
* Device specific ioctls should only be in their respective headers
* The device specific ioctl range is from 0x40 to 0x99.
@@ -806,6 +806,14 @@ struct drm_driver {
/* vga arb irq handler */
void (*vgaarb_irq)(struct drm_device *dev, bool state);
+ /* dumb alloc support */
+ int (*dumb_create)(struct drm_file *file_priv,
+ struct drm_device *dev, uint64_t size,
+ uint32_t *handle);
+ int (*dumb_map_offset)(struct drm_file *file_priv,
+ struct drm_device *dev, uint32_t handle,
+ uint64_t *offset);
+
/* Driver private ops for this object */
struct vm_operations_struct *gem_vm_ops;
@@ -803,4 +803,10 @@ extern int drm_add_modes_noedid(struct drm_connector *connector,
int hdisplay, int vdisplay);
extern bool drm_edid_is_valid(struct edid *edid);
+
+extern int drm_mode_create_dumb_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+extern int drm_mode_mmap_dumb_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+
#endif /* __DRM_CRTC_H__ */
@@ -343,4 +343,24 @@ struct drm_mode_crtc_page_flip {
__u64 user_data;
};
+/* create a dumb scanout buffer */
+struct drm_mode_create_dumb {
+ uint64_t size;
+ uint32_t handle;
+ uint32_t flags;
+};
+
+/* set up for mmap of a dumb scanout buffer */
+struct drm_mode_map_dumb {
+ /** Handle for the object being mapped. */
+ __u32 handle;
+ __u32 pad;
+ /**
+ * Fake offset to use for subsequent mmap call
+ *
+ * This is a fixed-size type for 32/64 compatibility.
+ */
+ __u64 offset;
+};
+
#endif