File Index
Files and directories
Sign in
FILE

vgem_drv.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/vgem/vgem_drv.c C
  1/*
  2 * Copyright 2011 Red Hat, Inc.
  3 * Copyright © 2014 The Chromium OS Authors
  4 *
  5 * Permission is hereby granted, free of charge, to any person obtaining a
  6 * copy of this software and associated documentation files (the "Software")
  7 * to deal in the software without restriction, including without limitation
  8 * on the rights to use, copy, modify, merge, publish, distribute, sub
  9 * license, and/or sell copies of the Software, and to permit persons to whom
 10 * them Software is furnished to do so, subject to the following conditions:
 11 *
 12 * The above copyright notice and this permission notice (including the next
 13 * paragraph) shall be included in all copies or substantial portions of the
 14 * Software.
 15 *
 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTIBILITY,
 18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
 19 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER
 20 * IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF OR IN
 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 22 *
 23 * Authors:
 24 *	Adam Jackson <ajax@redhat.com>
 25 *	Ben Widawsky <ben@bwidawsk.net>
 26 */
 27
 28/*
 29 * This is vgem, a (non-hardware-backed) GEM service.  This is used by Mesa's
 30 * software renderer and the X server for efficient buffer sharing.
 31 */
 32
 33#include <linux/dma-buf.h>
 34#include <linux/module.h>
 35#include <linux/device/faux.h>
 36#include <linux/shmem_fs.h>
 37#include <linux/vmalloc.h>
 38
 39#include <drm/drm_drv.h>
 40#include <drm/drm_file.h>
 41#include <drm/drm_gem_shmem_helper.h>
 42#include <drm/drm_ioctl.h>
 43#include <drm/drm_managed.h>
 44#include <drm/drm_prime.h>
 45
 46#include "vgem_drv.h"
 47
 48#define DRIVER_NAME	"vgem"
 49#define DRIVER_DESC	"Virtual GEM provider"
 50#define DRIVER_MAJOR	1
 51#define DRIVER_MINOR	0
 52
 53static struct vgem_device {
 54	struct drm_device drm;
 55	struct faux_device *faux_dev;
 56} *vgem_device;
 57
 58static int vgem_open(struct drm_device *dev, struct drm_file *file)
 59{
 60	struct vgem_file *vfile;
 61	int ret;
 62
 63	vfile = kzalloc(sizeof(*vfile), GFP_KERNEL);
 64	if (!vfile)
 65		return -ENOMEM;
 66
 67	file->driver_priv = vfile;
 68
 69	ret = vgem_fence_open(vfile);
 70	if (ret) {
 71		kfree(vfile);
 72		return ret;
 73	}
 74
 75	return 0;
 76}
 77
 78static void vgem_postclose(struct drm_device *dev, struct drm_file *file)
 79{
 80	struct vgem_file *vfile = file->driver_priv;
 81
 82	vgem_fence_close(vfile);
 83	kfree(vfile);
 84}
 85
 86static struct drm_ioctl_desc vgem_ioctls[] = {
 87	DRM_IOCTL_DEF_DRV(VGEM_FENCE_ATTACH, vgem_fence_attach_ioctl, DRM_RENDER_ALLOW),
 88	DRM_IOCTL_DEF_DRV(VGEM_FENCE_SIGNAL, vgem_fence_signal_ioctl, DRM_RENDER_ALLOW),
 89};
 90
 91DEFINE_DRM_GEM_FOPS(vgem_driver_fops);
 92
 93static struct drm_gem_object *vgem_gem_create_object(struct drm_device *dev, size_t size)
 94{
 95	struct drm_gem_shmem_object *obj;
 96
 97	obj = kzalloc(sizeof(*obj), GFP_KERNEL);
 98	if (!obj)
 99		return ERR_PTR(-ENOMEM);
100
101	/*
102	 * vgem doesn't have any begin/end cpu access ioctls, therefore must use
103	 * coherent memory or dma-buf sharing just wont work.
104	 */
105	obj->map_wc = true;
106
107	return &obj->base;
108}
109
110static const struct drm_driver vgem_driver = {
111	.driver_features		= DRIVER_GEM | DRIVER_RENDER,
112	.open				= vgem_open,
113	.postclose			= vgem_postclose,
114	.ioctls				= vgem_ioctls,
115	.num_ioctls 			= ARRAY_SIZE(vgem_ioctls),
116	.fops				= &vgem_driver_fops,
117
118	DRM_GEM_SHMEM_DRIVER_OPS,
119	.gem_create_object		= vgem_gem_create_object,
120
121	.name	= DRIVER_NAME,
122	.desc	= DRIVER_DESC,
123	.major	= DRIVER_MAJOR,
124	.minor	= DRIVER_MINOR,
125};
126
127static int __init vgem_init(void)
128{
129	int ret;
130	struct faux_device *fdev;
131
132	fdev = faux_device_create("vgem", NULL, NULL);
133	if (!fdev)
134		return -ENODEV;
135
136	if (!devres_open_group(&fdev->dev, NULL, GFP_KERNEL)) {
137		ret = -ENOMEM;
138		goto out_unregister;
139	}
140
141	dma_coerce_mask_and_coherent(&fdev->dev,
142				     DMA_BIT_MASK(64));
143
144	vgem_device = devm_drm_dev_alloc(&fdev->dev, &vgem_driver,
145					 struct vgem_device, drm);
146	if (IS_ERR(vgem_device)) {
147		ret = PTR_ERR(vgem_device);
148		goto out_devres;
149	}
150	vgem_device->faux_dev = fdev;
151
152	/* Final step: expose the device/driver to userspace */
153	ret = drm_dev_register(&vgem_device->drm, 0);
154	if (ret)
155		goto out_devres;
156
157	return 0;
158
159out_devres:
160	devres_release_group(&fdev->dev, NULL);
161out_unregister:
162	faux_device_destroy(fdev);
163	return ret;
164}
165
166static void __exit vgem_exit(void)
167{
168	struct faux_device *fdev = vgem_device->faux_dev;
169
170	drm_dev_unregister(&vgem_device->drm);
171	devres_release_group(&fdev->dev, NULL);
172	faux_device_destroy(fdev);
173}
174
175module_init(vgem_init);
176module_exit(vgem_exit);
177
178MODULE_AUTHOR("Red Hat, Inc.");
179MODULE_AUTHOR("Intel Corporation");
180MODULE_DESCRIPTION(DRIVER_DESC);
181MODULE_LICENSE("GPL and additional rights");
~/ Read-only file preview.