10 #include <tdm_helper.h>
11 #include <tbm_drm_helper.h>
15 #define SPRD_DRM_NAME "sprd"
17 static tdm_sprd_data *sprd_data;
20 _tdm_sprd_open_drm(void)
24 fd = drmOpen(SPRD_DRM_NAME, NULL);
26 TDM_ERR("Cannot open '%s' drm", SPRD_DRM_NAME);
31 struct udev_enumerate *e;
32 struct udev_list_entry *entry;
33 struct udev_device *device, *drm_device, *device_parent;
36 TDM_WRN("Cannot open drm device.. search by udev");
39 TDM_ERR("fail to initialize udev context\n");
43 /* Will try to find sys path /sprd-drm/drm/card0 */
44 e = udev_enumerate_new(udev);
45 udev_enumerate_add_match_subsystem(e, "drm");
46 udev_enumerate_add_match_sysname(e, "card[0-9]*");
47 udev_enumerate_scan_devices(e);
50 udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
51 device = udev_device_new_from_syspath(udev_enumerate_get_udev(e),
52 udev_list_entry_get_name
54 device_parent = udev_device_get_parent(device);
55 /* Not need unref device_parent. device_parent and device have same refcnt */
57 if (strcmp(udev_device_get_sysname(device_parent), "sprd-drm") == 0) {
59 TDM_DBG("Found drm device: '%s' (%s)\n",
60 udev_device_get_syspath(drm_device),
61 udev_device_get_sysname(device_parent));
65 udev_device_unref(device);
68 if (drm_device == NULL) {
69 TDM_ERR("fail to find drm device\n");
70 udev_enumerate_unref(e);
75 filename = udev_device_get_devnode(drm_device);
77 fd = open(filename, O_RDWR | O_CLOEXEC);
79 TDM_ERR("Cannot open drm device(%s)\n", filename);
81 udev_device_unref(drm_device);
82 udev_enumerate_unref(e);
89 drmCtlInstHandler(fd, 78);
96 tdm_sprd_deinit(tdm_backend_data *bdata)
98 if (sprd_data != bdata)
102 tdm_sprd_display_destroy_buffer_list(sprd_data);
103 tdm_sprd_display_destroy_output_list(sprd_data);
104 tdm_sprd_display_deinit_event_handling(sprd_data);
106 if (sprd_data->drm_fd >= 0)
107 close(sprd_data->drm_fd);
114 tdm_sprd_init(tdm_display *dpy, tdm_error *error)
116 tdm_func_display sprd_func_display;
117 tdm_func_output sprd_func_output;
118 tdm_func_layer sprd_func_layer;
119 tdm_func_hwc sprd_func_hwc;
120 tdm_func_hwc_window sprd_func_hwc_window;
121 tdm_func_pp sprd_func_pp;
122 tdm_func_capture sprd_func_capture;
127 TDM_ERR("display is null");
129 *error = TDM_ERROR_INVALID_PARAMETER;
134 TDM_ERR("failed_l: init twice");
136 *error = TDM_ERROR_BAD_REQUEST;
140 sprd_data = calloc(1, sizeof(tdm_sprd_data));
142 TDM_ERR("alloc failed_l");
144 *error = TDM_ERROR_OUT_OF_MEMORY;
148 str = getenv("TDM_HWC");
150 sprd_data->hwc_mode = strtol(str, NULL, 10);
152 LIST_INITHEAD(&sprd_data->output_list);
153 LIST_INITHEAD(&sprd_data->buffer_list);
155 memset(&sprd_func_display, 0, sizeof(sprd_func_display));
156 sprd_func_display.display_get_capability = sprd_display_get_capability;
157 sprd_func_display.display_get_pp_capability = sprd_display_get_pp_capability;
158 sprd_func_display.display_get_outputs = sprd_display_get_outputs;
159 sprd_func_display.display_get_fd = sprd_display_get_fd;
160 sprd_func_display.display_handle_events = sprd_display_handle_events;
161 sprd_func_display.display_create_pp = sprd_display_create_pp;
162 sprd_func_display.display_get_capture_capability = sprd_capture_get_capability;
164 memset(&sprd_func_output, 0, sizeof(sprd_func_output));
165 sprd_func_output.output_get_capability = sprd_output_get_capability;
166 sprd_func_output.output_get_layers = sprd_output_get_layers;
167 sprd_func_output.output_set_property = sprd_output_set_property;
168 sprd_func_output.output_get_property = sprd_output_get_property;
169 sprd_func_output.output_wait_vblank = sprd_output_wait_vblank;
170 sprd_func_output.output_set_vblank_handler = sprd_output_set_vblank_handler;
171 sprd_func_output.output_commit = sprd_output_commit;
172 sprd_func_output.output_set_commit_handler = sprd_output_set_commit_handler;
173 sprd_func_output.output_set_dpms = sprd_output_set_dpms;
174 sprd_func_output.output_get_dpms = sprd_output_get_dpms;
175 sprd_func_output.output_set_mode = sprd_output_set_mode;
176 sprd_func_output.output_get_mode = sprd_output_get_mode;
177 sprd_func_output.output_create_capture = sprd_capture_create;
178 if (sprd_data->hwc_mode) {
179 sprd_func_output.output_get_hwc = sprd_output_get_hwc;
181 memset(&sprd_func_hwc, 0, sizeof(sprd_func_hwc));
182 sprd_func_hwc.hwc_create_window = sprd_hwc_create_window;
183 sprd_func_hwc.hwc_get_supported_formats = sprd_hwc_get_supported_formats;
184 sprd_func_hwc.hwc_get_available_properties = sprd_hwc_get_available_properties;
185 sprd_func_hwc.hwc_get_client_target_buffer_queue = sprd_hwc_get_client_target_buffer_queue;
186 sprd_func_hwc.hwc_set_client_target_buffer = sprd_hwc_set_client_target_buffer;
187 sprd_func_hwc.hwc_validate = sprd_hwc_validate;
188 sprd_func_hwc.hwc_get_changed_composition_types = sprd_hwc_get_changed_composition_types;
189 sprd_func_hwc.hwc_accept_changes = sprd_hwc_accept_changes;
190 sprd_func_hwc.hwc_commit = sprd_hwc_commit;
191 sprd_func_hwc.hwc_set_commit_handler = sprd_hwc_set_commit_handler;
193 memset(&sprd_func_hwc_window, 0, sizeof(sprd_func_hwc_window));
194 sprd_func_hwc_window.hwc_window_destroy = sprd_hwc_window_destroy;
195 sprd_func_hwc_window.hwc_window_get_buffer_queue = NULL;
196 sprd_func_hwc_window.hwc_window_set_composition_type = sprd_hwc_window_set_composition_type;
197 sprd_func_hwc_window.hwc_window_set_buffer_damage = sprd_hwc_window_set_buffer_damage;
198 sprd_func_hwc_window.hwc_window_set_info = sprd_hwc_window_set_info;
199 sprd_func_hwc_window.hwc_window_get_info = sprd_hwc_window_get_info;
200 sprd_func_hwc_window.hwc_window_set_buffer = sprd_hwc_window_set_buffer;
201 sprd_func_hwc_window.hwc_window_set_property = sprd_hwc_window_set_property;
202 sprd_func_hwc_window.hwc_window_get_property = sprd_hwc_window_get_property;
205 memset(&sprd_func_layer, 0, sizeof(sprd_func_layer));
206 sprd_func_layer.layer_get_capability = sprd_layer_get_capability;
207 sprd_func_layer.layer_set_property = sprd_layer_set_property;
208 sprd_func_layer.layer_get_property = sprd_layer_get_property;
209 sprd_func_layer.layer_set_info = sprd_layer_set_info;
210 sprd_func_layer.layer_get_info = sprd_layer_get_info;
211 sprd_func_layer.layer_set_buffer = sprd_layer_set_buffer;
212 sprd_func_layer.layer_unset_buffer = sprd_layer_unset_buffer;
213 sprd_func_layer.layer_get_buffer_flags = sprd_layer_get_buffer_flags;
215 memset(&sprd_func_pp, 0, sizeof(sprd_func_pp));
216 sprd_func_pp.pp_destroy = sprd_pp_destroy;
217 sprd_func_pp.pp_set_info = sprd_pp_set_info;
218 sprd_func_pp.pp_attach = sprd_pp_attach;
219 sprd_func_pp.pp_commit = sprd_pp_commit;
220 sprd_func_pp.pp_set_done_handler = sprd_pp_set_done_handler;
222 memset(&sprd_func_capture, 0, sizeof(sprd_func_capture));
223 sprd_func_capture.capture_attach = sprd_capture_attach;
224 sprd_func_capture.capture_commit = sprd_capture_commit;
225 sprd_func_capture.capture_destroy = sprd_capture_destroy;
226 sprd_func_capture.capture_set_done_handler = sprd_capture_set_done_handler;
227 sprd_func_capture.capture_set_info = sprd_capture_set_info;
229 ret = tdm_backend_register_func_display(dpy, &sprd_func_display);
230 if (ret != TDM_ERROR_NONE)
233 ret = tdm_backend_register_func_output(dpy, &sprd_func_output);
234 if (ret != TDM_ERROR_NONE)
237 ret = tdm_backend_register_func_layer(dpy, &sprd_func_layer);
238 if (ret != TDM_ERROR_NONE)
241 if (sprd_data->hwc_mode) {
242 ret = tdm_backend_register_func_hwc_window(dpy, &sprd_func_hwc_window);
243 if (ret != TDM_ERROR_NONE)
248 ret = tdm_backend_register_func_pp(dpy, &sprd_func_pp);
249 if (ret != TDM_ERROR_NONE)
252 ret = tdm_backend_register_func_capture(dpy, &sprd_func_capture);
253 if (ret != TDM_ERROR_NONE)
256 sprd_data->dpy = dpy;
257 sprd_data->drm_fd = -1;
259 /* The drm master fd can be opened by a tbm backend module in
260 * tbm_bufmgr_init() time. In this case, we just get it from tbm.
262 sprd_data->drm_fd = tbm_drm_helper_get_master_fd();
263 if (sprd_data->drm_fd < 0) {
264 sprd_data->drm_fd = _tdm_sprd_open_drm();
266 if (sprd_data->drm_fd < 0) {
267 ret = TDM_ERROR_OPERATION_FAILED;
271 tbm_drm_helper_set_tbm_master_fd(sprd_data->drm_fd);
274 TDM_INFO("master fd(%d)", sprd_data->drm_fd);
277 if (drmSetClientCap(sprd_data->drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) < 0)
278 TDM_WRN("Set DRM_CLIENT_CAP_UNIVERSAL_PLANES failed_l");
281 ret = tdm_sprd_display_create_output_list(sprd_data);
282 if (ret != TDM_ERROR_NONE)
285 ret = tdm_sprd_display_init_event_handling(sprd_data);
286 if (ret != TDM_ERROR_NONE)
289 *error = TDM_ERROR_NONE;
291 TDM_INFO("init success!");
293 return (tdm_backend_data *)sprd_data;
298 tdm_sprd_deinit(sprd_data);
300 TDM_ERR("init failed!");
304 tdm_backend_module tdm_backend_module_data = {
307 TDM_BACKEND_ABI_VERSION,