xref: /openbsd-src/sys/dev/pci/drm/drm_gem_framebuffer_helper.c (revision f005ef32267c16bdb134f0e9fa4477dbe07c263a)
1 /* Public domain. */
2 
3 #include <drm/drm_gem.h>
4 #include <drm/drm_framebuffer.h>
5 #include <drm/drm_modeset_helper.h>
6 
7 void
drm_gem_fb_destroy(struct drm_framebuffer * fb)8 drm_gem_fb_destroy(struct drm_framebuffer *fb)
9 {
10 	int i;
11 
12 	for (i = 0; i < 4; i++)
13 		drm_gem_object_put(fb->obj[i]);
14 	drm_framebuffer_cleanup(fb);
15 	free(fb, M_DRM, 0);
16 }
17 
18 int
drm_gem_fb_create_handle(struct drm_framebuffer * fb,struct drm_file * file,unsigned int * handle)19 drm_gem_fb_create_handle(struct drm_framebuffer *fb, struct drm_file *file,
20     unsigned int *handle)
21 {
22 	return drm_gem_handle_create(file, fb->obj[0], handle);
23 }
24 
25 const struct drm_framebuffer_funcs drm_gem_fb_funcs = {
26 	.create_handle = drm_gem_fb_create_handle,
27 	.destroy = drm_gem_fb_destroy,
28 };
29 
30 struct drm_framebuffer *
drm_gem_fb_create(struct drm_device * dev,struct drm_file * file,const struct drm_mode_fb_cmd2 * cmd)31 drm_gem_fb_create(struct drm_device *dev, struct drm_file *file,
32 		  const struct drm_mode_fb_cmd2 *cmd)
33 {
34 	struct drm_framebuffer *fb;
35 	const struct drm_format_info *info;
36 	struct drm_gem_object *gem_obj;
37 	int error;
38 
39 	info = drm_get_format_info(dev, cmd);
40 	if (!info)
41 		return ERR_PTR(-EINVAL);
42 
43 	KASSERT(info->num_planes == 1);
44 
45 	gem_obj = drm_gem_object_lookup(file, cmd->handles[0]);
46 	if (gem_obj == NULL)
47 		return ERR_PTR(-ENOENT);
48 
49 	fb = malloc(sizeof(*fb), M_DRM, M_ZERO | M_WAITOK);
50 
51 	drm_helper_mode_fill_fb_struct(dev, fb, cmd);
52 	fb->obj[0] = gem_obj;
53 
54 	error = drm_framebuffer_init(dev, fb, &drm_gem_fb_funcs);
55 	if (error != 0)
56 		goto dealloc;
57 
58 	return fb;
59 
60 dealloc:
61 	drm_framebuffer_cleanup(fb);
62 	free(fb, M_DRM, sizeof(*fb));
63 	drm_gem_object_put(gem_obj);
64 
65 	return ERR_PTR(error);
66 }
67 
68 struct drm_gem_object *
drm_gem_fb_get_obj(struct drm_framebuffer * fb,unsigned int plane)69 drm_gem_fb_get_obj(struct drm_framebuffer *fb, unsigned int plane)
70 {
71 	if (plane < nitems(fb->obj))
72 		return fb->obj[plane];
73 	return NULL;
74 }
75