1 #include "gem.h"
2 
3 #include "gem_msm.h"
4 
5 struct gem_driver_lookup
6 {
7 	const char name[16];
8 	struct gem_driver *driver;
9 };
10 
11 static struct gem_driver_lookup drivers[] = {
12 	{
13 		.name = "msm_drm",
14 		.driver = &gem_msm_driver
15 	}
16 };
17 
num_drivers()18 static inline size_t num_drivers()
19 {
20 	return ARRAY_SIZE(drivers);
21 }
22 
gem_get_driver(int drm_fd)23 struct gem_driver *gem_get_driver(int drm_fd)
24 {
25 	char name[16] = {0};
26 	drm_version_t version = {};
27 
28 	version.name_len = sizeof(name);
29 	version.name = name;
30 
31 	if (drmIoctl(drm_fd, DRM_IOCTL_VERSION, &version))
32 	{
33 		return NULL;
34 	}
35 
36 	for (struct gem_driver_lookup *di = drivers;
37 	     di - drivers < num_drivers();
38 	     ++di)
39 	{
40 		if (!strncmp(name, di->name, sizeof(name)))
41 		{
42 			return di->driver;
43 		}
44 	}
45 
46 	return NULL;
47 }
48 
gem_size(int drm_fd,size_t * size,uint32_t gem_handle)49 int gem_size(int drm_fd, size_t *size, uint32_t gem_handle)
50 {
51 	struct drm_gem_flink drm_gem_flink_arg = {
52 		.handle = gem_handle,
53 		.name = 0
54 	};
55 
56 	if (drmIoctl(drm_fd,
57 		     DRM_IOCTL_GEM_FLINK,
58 		     &drm_gem_flink_arg))
59 	{
60 		return -1;
61 	}
62 
63 	struct drm_gem_open drm_gem_open_arg = {
64 		.name = drm_gem_flink_arg.name,
65 		.handle = 0,
66 		.size = 0
67 	};
68 
69 	if (drmIoctl(drm_fd,
70 		     DRM_IOCTL_GEM_OPEN,
71 		     &drm_gem_open_arg))
72 	{
73 		return -1;
74 	}
75 
76 	*size = drm_gem_open_arg.size;
77 
78 	if (drm_gem_open_arg.handle != gem_handle)
79 	{
80 		gem_release_handle(drm_fd, drm_gem_open_arg.handle);
81 	}
82 
83 	return 0;
84 }
85 
gem_release_handle(int drm_fd,uint32_t gem_handle)86 void gem_release_handle(int drm_fd, uint32_t gem_handle)
87 {
88 	struct drm_gem_close drm_gem_close_arg = {
89 		.handle = gem_handle,
90 		.pad = 0
91 	};
92 
93 	drmIoctl(drm_fd, DRM_IOCTL_GEM_CLOSE, &drm_gem_close_arg);
94 }
95 
drm_fb_for_gem_handle(int drm_fd,uint32_t * fb_id,uint32_t gem_handle,const struct fb_configuration * fb_config)96 int drm_fb_for_gem_handle(int drm_fd, uint32_t *fb_id, uint32_t gem_handle,
97 			     const struct fb_configuration *fb_config)
98 {
99 	struct drm_mode_fb_cmd2 drm_mode_addfb2_arg = {
100 		.fb_id = 0,
101 		.width = fb_config->width,
102 		.height = fb_config->height,
103 		.pixel_format = fb_config->pixel_format,
104 		.flags = DRM_MODE_FB_MODIFIERS,
105 		.handles = { gem_handle, 0, 0, 0 },
106 		.pitches = { fb_config->width * fb_config->pixel_size, 0, 0, 0 },
107 		.offsets = { 0, 0, 0, 0 },
108 		.modifier = { 0 }
109 	};
110 
111 	if (drmIoctl(drm_fd, DRM_IOCTL_MODE_ADDFB2, &drm_mode_addfb2_arg))
112 	{
113 		return -1;
114 	}
115 
116 	*fb_id = drm_mode_addfb2_arg.fb_id;
117 
118 	return 0;
119 }
120