• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 Google, Inc.
3  *
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  */
14 
15 #include <linux/kthread.h>
16 #include <linux/mutex.h>
17 #include <linux/slab.h>
18 
19 #include "sw_sync.h"
20 
21 #include <video/adf.h>
22 #include <video/adf_client.h>
23 #include <video/adf_format.h>
24 
25 #include "adf.h"
26 
vsync_active(u8 state)27 static inline bool vsync_active(u8 state)
28 {
29 	return state == DRM_MODE_DPMS_ON || state == DRM_MODE_DPMS_STANDBY;
30 }
31 
32 /**
33  * adf_interface_blank - set interface's DPMS state
34  *
35  * @intf: the interface
36  * @state: one of %DRM_MODE_DPMS_*
37  *
38  * Returns 0 on success or -errno on failure.
39  */
adf_interface_blank(struct adf_interface * intf,u8 state)40 int adf_interface_blank(struct adf_interface *intf, u8 state)
41 {
42 	struct adf_device *dev = adf_interface_parent(intf);
43 	u8 prev_state;
44 	bool disable_vsync;
45 	bool enable_vsync;
46 	int ret = 0;
47 	struct adf_event_refcount *vsync_refcount;
48 
49 	if (!intf->ops || !intf->ops->blank)
50 		return -EOPNOTSUPP;
51 
52 	if (state > DRM_MODE_DPMS_OFF)
53 		return -EINVAL;
54 
55 	mutex_lock(&dev->client_lock);
56 	if (state != DRM_MODE_DPMS_ON)
57 		flush_kthread_worker(&dev->post_worker);
58 	mutex_lock(&intf->base.event_lock);
59 
60 	vsync_refcount = adf_obj_find_event_refcount(&intf->base,
61 			ADF_EVENT_VSYNC);
62 	if (!vsync_refcount) {
63 		ret = -ENOMEM;
64 		goto done;
65 	}
66 
67 	prev_state = intf->dpms_state;
68 	if (prev_state == state) {
69 		ret = -EBUSY;
70 		goto done;
71 	}
72 
73 	disable_vsync = vsync_active(prev_state) &&
74 			!vsync_active(state) &&
75 			vsync_refcount->refcount;
76 	enable_vsync = !vsync_active(prev_state) &&
77 			vsync_active(state) &&
78 			vsync_refcount->refcount;
79 
80 	if (disable_vsync)
81 		intf->base.ops->set_event(&intf->base, ADF_EVENT_VSYNC,
82 				false);
83 
84 	ret = intf->ops->blank(intf, state);
85 	if (ret < 0) {
86 		if (disable_vsync)
87 			intf->base.ops->set_event(&intf->base, ADF_EVENT_VSYNC,
88 					true);
89 		goto done;
90 	}
91 
92 	if (enable_vsync)
93 		intf->base.ops->set_event(&intf->base, ADF_EVENT_VSYNC,
94 				true);
95 
96 	intf->dpms_state = state;
97 done:
98 	mutex_unlock(&intf->base.event_lock);
99 	mutex_unlock(&dev->client_lock);
100 	return ret;
101 }
102 EXPORT_SYMBOL(adf_interface_blank);
103 
104 /**
105  * adf_interface_blank - get interface's current DPMS state
106  *
107  * @intf: the interface
108  *
109  * Returns one of %DRM_MODE_DPMS_*.
110  */
adf_interface_dpms_state(struct adf_interface * intf)111 u8 adf_interface_dpms_state(struct adf_interface *intf)
112 {
113 	struct adf_device *dev = adf_interface_parent(intf);
114 	u8 dpms_state;
115 
116 	mutex_lock(&dev->client_lock);
117 	dpms_state = intf->dpms_state;
118 	mutex_unlock(&dev->client_lock);
119 
120 	return dpms_state;
121 }
122 EXPORT_SYMBOL(adf_interface_dpms_state);
123 
124 /**
125  * adf_interface_current_mode - get interface's current display mode
126  *
127  * @intf: the interface
128  * @mode: returns the current mode
129  */
adf_interface_current_mode(struct adf_interface * intf,struct drm_mode_modeinfo * mode)130 void adf_interface_current_mode(struct adf_interface *intf,
131 		struct drm_mode_modeinfo *mode)
132 {
133 	struct adf_device *dev = adf_interface_parent(intf);
134 
135 	mutex_lock(&dev->client_lock);
136 	memcpy(mode, &intf->current_mode, sizeof(*mode));
137 	mutex_unlock(&dev->client_lock);
138 }
139 EXPORT_SYMBOL(adf_interface_current_mode);
140 
141 /**
142  * adf_interface_modelist - get interface's modelist
143  *
144  * @intf: the interface
145  * @modelist: storage for the modelist (optional)
146  * @n_modes: length of @modelist
147  *
148  * If @modelist is not NULL, adf_interface_modelist() will copy up to @n_modes
149  * modelist entries into @modelist.
150  *
151  * Returns the length of the modelist.
152  */
adf_interface_modelist(struct adf_interface * intf,struct drm_mode_modeinfo * modelist,size_t n_modes)153 size_t adf_interface_modelist(struct adf_interface *intf,
154 		struct drm_mode_modeinfo *modelist, size_t n_modes)
155 {
156 	unsigned long flags;
157 	size_t retval;
158 
159 	read_lock_irqsave(&intf->hotplug_modelist_lock, flags);
160 	if (modelist)
161 		memcpy(modelist, intf->modelist, sizeof(modelist[0]) *
162 				min(n_modes, intf->n_modes));
163 	retval = intf->n_modes;
164 	read_unlock_irqrestore(&intf->hotplug_modelist_lock, flags);
165 
166 	return retval;
167 }
168 EXPORT_SYMBOL(adf_interface_modelist);
169 
170 /**
171  * adf_interface_set_mode - set interface's display mode
172  *
173  * @intf: the interface
174  * @mode: the new mode
175  *
176  * Returns 0 on success or -errno on failure.
177  */
adf_interface_set_mode(struct adf_interface * intf,struct drm_mode_modeinfo * mode)178 int adf_interface_set_mode(struct adf_interface *intf,
179 		struct drm_mode_modeinfo *mode)
180 {
181 	struct adf_device *dev = adf_interface_parent(intf);
182 	int ret = 0;
183 
184 	if (!intf->ops || !intf->ops->modeset)
185 		return -EOPNOTSUPP;
186 
187 	mutex_lock(&dev->client_lock);
188 	flush_kthread_worker(&dev->post_worker);
189 
190 	ret = intf->ops->modeset(intf, mode);
191 	if (ret < 0)
192 		goto done;
193 
194 	memcpy(&intf->current_mode, mode, sizeof(*mode));
195 done:
196 	mutex_unlock(&dev->client_lock);
197 	return ret;
198 }
199 EXPORT_SYMBOL(adf_interface_set_mode);
200 
201 /**
202  * adf_interface_screen_size - get size of screen connected to interface
203  *
204  * @intf: the interface
205  * @width_mm: returns the screen width in mm
206  * @height_mm: returns the screen width in mm
207  *
208  * Returns 0 on success or -errno on failure.
209  */
adf_interface_get_screen_size(struct adf_interface * intf,u16 * width_mm,u16 * height_mm)210 int adf_interface_get_screen_size(struct adf_interface *intf, u16 *width_mm,
211 		u16 *height_mm)
212 {
213 	struct adf_device *dev = adf_interface_parent(intf);
214 	int ret;
215 
216 	if (!intf->ops || !intf->ops->screen_size)
217 		return -EOPNOTSUPP;
218 
219 	mutex_lock(&dev->client_lock);
220 	ret = intf->ops->screen_size(intf, width_mm, height_mm);
221 	mutex_unlock(&dev->client_lock);
222 
223 	return ret;
224 }
225 EXPORT_SYMBOL(adf_interface_get_screen_size);
226 
227 /**
228  * adf_overlay_engine_supports_format - returns whether a format is in an
229  * overlay engine's supported list
230  *
231  * @eng: the overlay engine
232  * @format: format fourcc
233  */
adf_overlay_engine_supports_format(struct adf_overlay_engine * eng,u32 format)234 bool adf_overlay_engine_supports_format(struct adf_overlay_engine *eng,
235 		u32 format)
236 {
237 	size_t i;
238 	for (i = 0; i < eng->ops->n_supported_formats; i++)
239 		if (format == eng->ops->supported_formats[i])
240 			return true;
241 
242 	return false;
243 }
244 EXPORT_SYMBOL(adf_overlay_engine_supports_format);
245 
adf_buffer_validate(struct adf_buffer * buf)246 static int adf_buffer_validate(struct adf_buffer *buf)
247 {
248 	struct adf_overlay_engine *eng = buf->overlay_engine;
249 	struct device *dev = &eng->base.dev;
250 	struct adf_device *parent = adf_overlay_engine_parent(eng);
251 	u8 hsub, vsub, num_planes, cpp[ADF_MAX_PLANES], i;
252 
253 	if (!adf_overlay_engine_supports_format(eng, buf->format)) {
254 		char format_str[ADF_FORMAT_STR_SIZE];
255 		adf_format_str(buf->format, format_str);
256 		dev_err(dev, "unsupported format %s\n", format_str);
257 		return -EINVAL;
258 	}
259 
260 	if (!adf_format_is_standard(buf->format))
261 		return parent->ops->validate_custom_format(parent, buf);
262 
263 	hsub = adf_format_horz_chroma_subsampling(buf->format);
264 	vsub = adf_format_vert_chroma_subsampling(buf->format);
265 	num_planes = adf_format_num_planes(buf->format);
266 	for (i = 0; i < num_planes; i++)
267 		cpp[i] = adf_format_plane_cpp(buf->format, i);
268 
269 	return adf_format_validate_yuv(parent, buf, num_planes, hsub, vsub,
270 			cpp);
271 }
272 
adf_buffer_map(struct adf_device * dev,struct adf_buffer * buf,struct adf_buffer_mapping * mapping)273 static int adf_buffer_map(struct adf_device *dev, struct adf_buffer *buf,
274 		struct adf_buffer_mapping *mapping)
275 {
276 	int ret = 0;
277 	size_t i;
278 
279 	for (i = 0; i < buf->n_planes; i++) {
280 		struct dma_buf_attachment *attachment;
281 		struct sg_table *sg_table;
282 
283 		attachment = dma_buf_attach(buf->dma_bufs[i], dev->dev);
284 		if (IS_ERR(attachment)) {
285 			ret = PTR_ERR(attachment);
286 			dev_err(&dev->base.dev, "attaching plane %zu failed: %d\n",
287 					i, ret);
288 			goto done;
289 		}
290 		mapping->attachments[i] = attachment;
291 
292 		sg_table = dma_buf_map_attachment(attachment, DMA_TO_DEVICE);
293 		if (IS_ERR(sg_table)) {
294 			ret = PTR_ERR(sg_table);
295 			dev_err(&dev->base.dev, "mapping plane %zu failed: %d",
296 					i, ret);
297 			goto done;
298 		} else if (!sg_table) {
299 			ret = -ENOMEM;
300 			dev_err(&dev->base.dev, "mapping plane %zu failed\n",
301 					i);
302 			goto done;
303 		}
304 		mapping->sg_tables[i] = sg_table;
305 	}
306 
307 done:
308 	if (ret < 0)
309 		adf_buffer_mapping_cleanup(mapping, buf);
310 
311 	return ret;
312 }
313 
adf_sw_complete_fence(struct adf_device * dev)314 static struct sync_fence *adf_sw_complete_fence(struct adf_device *dev)
315 {
316 	struct sync_pt *pt;
317 	struct sync_fence *complete_fence;
318 
319 	if (!dev->timeline) {
320 		dev->timeline = sw_sync_timeline_create(dev->base.name);
321 		if (!dev->timeline)
322 			return ERR_PTR(-ENOMEM);
323 		dev->timeline_max = 1;
324 	}
325 
326 	dev->timeline_max++;
327 	pt = sw_sync_pt_create(dev->timeline, dev->timeline_max);
328 	if (!pt)
329 		goto err_pt_create;
330 	complete_fence = sync_fence_create(dev->base.name, pt);
331 	if (!complete_fence)
332 		goto err_fence_create;
333 
334 	return complete_fence;
335 
336 err_fence_create:
337 	sync_pt_free(pt);
338 err_pt_create:
339 	dev->timeline_max--;
340 	return ERR_PTR(-ENOSYS);
341 }
342 
343 /**
344  * adf_device_post - flip to a new set of buffers
345  *
346  * @dev: device targeted by the flip
347  * @intfs: interfaces targeted by the flip
348  * @n_intfs: number of targeted interfaces
349  * @bufs: description of buffers displayed
350  * @n_bufs: number of buffers displayed
351  * @custom_data: driver-private data
352  * @custom_data_size: size of driver-private data
353  *
354  * adf_device_post() will copy @intfs, @bufs, and @custom_data, so they may
355  * point to variables on the stack.  adf_device_post() also takes its own
356  * reference on each of the dma-bufs in @bufs.  The adf_device_post_nocopy()
357  * variant transfers ownership of these resources to ADF instead.
358  *
359  * On success, returns a sync fence which signals when the buffers are removed
360  * from the screen.  On failure, returns ERR_PTR(-errno).
361  */
adf_device_post(struct adf_device * dev,struct adf_interface ** intfs,size_t n_intfs,struct adf_buffer * bufs,size_t n_bufs,void * custom_data,size_t custom_data_size)362 struct sync_fence *adf_device_post(struct adf_device *dev,
363 		struct adf_interface **intfs, size_t n_intfs,
364 		struct adf_buffer *bufs, size_t n_bufs, void *custom_data,
365 		size_t custom_data_size)
366 {
367 	struct adf_interface **intfs_copy = NULL;
368 	struct adf_buffer *bufs_copy = NULL;
369 	void *custom_data_copy = NULL;
370 	struct sync_fence *ret;
371 	size_t i;
372 
373 	intfs_copy = kzalloc(sizeof(intfs_copy[0]) * n_intfs, GFP_KERNEL);
374 	if (!intfs_copy)
375 		return ERR_PTR(-ENOMEM);
376 
377 	bufs_copy = kzalloc(sizeof(bufs_copy[0]) * n_bufs, GFP_KERNEL);
378 	if (!bufs_copy) {
379 		ret = ERR_PTR(-ENOMEM);
380 		goto err_alloc;
381 	}
382 
383 	custom_data_copy = kzalloc(custom_data_size, GFP_KERNEL);
384 	if (!custom_data_copy) {
385 		ret = ERR_PTR(-ENOMEM);
386 		goto err_alloc;
387 	}
388 
389 	for (i = 0; i < n_bufs; i++) {
390 		size_t j;
391 		for (j = 0; j < bufs[i].n_planes; j++)
392 			get_dma_buf(bufs[i].dma_bufs[j]);
393 	}
394 
395 	memcpy(intfs_copy, intfs, sizeof(intfs_copy[0]) * n_intfs);
396 	memcpy(bufs_copy, bufs, sizeof(bufs_copy[0]) * n_bufs);
397 	memcpy(custom_data_copy, custom_data, custom_data_size);
398 
399 	ret = adf_device_post_nocopy(dev, intfs_copy, n_intfs, bufs_copy,
400 			n_bufs, custom_data_copy, custom_data_size);
401 	if (IS_ERR(ret))
402 		goto err_post;
403 
404 	return ret;
405 
406 err_post:
407 	for (i = 0; i < n_bufs; i++) {
408 		size_t j;
409 		for (j = 0; j < bufs[i].n_planes; j++)
410 			dma_buf_put(bufs[i].dma_bufs[j]);
411 	}
412 err_alloc:
413 	kfree(custom_data_copy);
414 	kfree(bufs_copy);
415 	kfree(intfs_copy);
416 	return ret;
417 }
418 EXPORT_SYMBOL(adf_device_post);
419 
420 /**
421  * adf_device_post_nocopy - flip to a new set of buffers
422  *
423  * adf_device_post_nocopy() has the same behavior as adf_device_post(),
424  * except ADF does not copy @intfs, @bufs, or @custom_data, and it does
425  * not take an extra reference on the dma-bufs in @bufs.
426  *
427  * @intfs, @bufs, and @custom_data must point to buffers allocated by
428  * kmalloc().  On success, ADF takes ownership of these buffers and the dma-bufs
429  * in @bufs, and will kfree()/dma_buf_put() them when they are no longer needed.
430  * On failure, adf_device_post_nocopy() does NOT take ownership of these
431  * buffers or the dma-bufs, and the caller must clean them up.
432  *
433  * adf_device_post_nocopy() is mainly intended for implementing ADF's ioctls.
434  * Clients may find the nocopy variant useful in limited cases, but most should
435  * call adf_device_post() instead.
436  */
adf_device_post_nocopy(struct adf_device * dev,struct adf_interface ** intfs,size_t n_intfs,struct adf_buffer * bufs,size_t n_bufs,void * custom_data,size_t custom_data_size)437 struct sync_fence *adf_device_post_nocopy(struct adf_device *dev,
438 		struct adf_interface **intfs, size_t n_intfs,
439 		struct adf_buffer *bufs, size_t n_bufs,
440 		void *custom_data, size_t custom_data_size)
441 {
442 	struct adf_pending_post *cfg;
443 	struct adf_buffer_mapping *mappings;
444 	struct sync_fence *ret;
445 	size_t i;
446 	int err;
447 
448 	cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
449 	if (!cfg)
450 		return ERR_PTR(-ENOMEM);
451 
452 	mappings = kzalloc(sizeof(mappings[0]) * n_bufs, GFP_KERNEL);
453 	if (!mappings) {
454 		ret = ERR_PTR(-ENOMEM);
455 		goto err_alloc;
456 	}
457 
458 	mutex_lock(&dev->client_lock);
459 
460 	for (i = 0; i < n_bufs; i++) {
461 		err = adf_buffer_validate(&bufs[i]);
462 		if (err < 0) {
463 			ret = ERR_PTR(err);
464 			goto err_buf;
465 		}
466 
467 		err = adf_buffer_map(dev, &bufs[i], &mappings[i]);
468 		if (err < 0) {
469 			ret = ERR_PTR(err);
470 			goto err_buf;
471 		}
472 	}
473 
474 	INIT_LIST_HEAD(&cfg->head);
475 	cfg->config.n_bufs = n_bufs;
476 	cfg->config.bufs = bufs;
477 	cfg->config.mappings = mappings;
478 	cfg->config.custom_data = custom_data;
479 	cfg->config.custom_data_size = custom_data_size;
480 
481 	err = dev->ops->validate(dev, &cfg->config, &cfg->state);
482 	if (err < 0) {
483 		ret = ERR_PTR(err);
484 		goto err_buf;
485 	}
486 
487 	mutex_lock(&dev->post_lock);
488 
489 	if (dev->ops->complete_fence)
490 		ret = dev->ops->complete_fence(dev, &cfg->config,
491 				cfg->state);
492 	else
493 		ret = adf_sw_complete_fence(dev);
494 
495 	if (IS_ERR(ret))
496 		goto err_fence;
497 
498 	list_add_tail(&cfg->head, &dev->post_list);
499 	queue_kthread_work(&dev->post_worker, &dev->post_work);
500 	mutex_unlock(&dev->post_lock);
501 	mutex_unlock(&dev->client_lock);
502 	kfree(intfs);
503 	return ret;
504 
505 err_fence:
506 	mutex_unlock(&dev->post_lock);
507 
508 err_buf:
509 	for (i = 0; i < n_bufs; i++)
510 		adf_buffer_mapping_cleanup(&mappings[i], &bufs[i]);
511 
512 	mutex_unlock(&dev->client_lock);
513 	kfree(mappings);
514 
515 err_alloc:
516 	kfree(cfg);
517 	return ret;
518 }
519 EXPORT_SYMBOL(adf_device_post_nocopy);
520 
adf_attachment_list_to_array(struct adf_device * dev,struct list_head * src,struct adf_attachment * dst,size_t size)521 static void adf_attachment_list_to_array(struct adf_device *dev,
522 		struct list_head *src, struct adf_attachment *dst, size_t size)
523 {
524 	struct adf_attachment_list *entry;
525 	size_t i = 0;
526 
527 	if (!dst)
528 		return;
529 
530 	list_for_each_entry(entry, src, head) {
531 		if (i == size)
532 			return;
533 		dst[i] = entry->attachment;
534 		i++;
535 	}
536 }
537 
538 /**
539  * adf_device_attachments - get device's list of active attachments
540  *
541  * @dev: the device
542  * @attachments: storage for the attachment list (optional)
543  * @n_attachments: length of @attachments
544  *
545  * If @attachments is not NULL, adf_device_attachments() will copy up to
546  * @n_attachments entries into @attachments.
547  *
548  * Returns the length of the active attachment list.
549  */
adf_device_attachments(struct adf_device * dev,struct adf_attachment * attachments,size_t n_attachments)550 size_t adf_device_attachments(struct adf_device *dev,
551 		struct adf_attachment *attachments, size_t n_attachments)
552 {
553 	size_t retval;
554 
555 	mutex_lock(&dev->client_lock);
556 	adf_attachment_list_to_array(dev, &dev->attached, attachments,
557 			n_attachments);
558 	retval = dev->n_attached;
559 	mutex_unlock(&dev->client_lock);
560 
561 	return retval;
562 }
563 EXPORT_SYMBOL(adf_device_attachments);
564 
565 /**
566  * adf_device_attachments_allowed - get device's list of allowed attachments
567  *
568  * @dev: the device
569  * @attachments: storage for the attachment list (optional)
570  * @n_attachments: length of @attachments
571  *
572  * If @attachments is not NULL, adf_device_attachments_allowed() will copy up to
573  * @n_attachments entries into @attachments.
574  *
575  * Returns the length of the allowed attachment list.
576  */
adf_device_attachments_allowed(struct adf_device * dev,struct adf_attachment * attachments,size_t n_attachments)577 size_t adf_device_attachments_allowed(struct adf_device *dev,
578 		struct adf_attachment *attachments, size_t n_attachments)
579 {
580 	size_t retval;
581 
582 	mutex_lock(&dev->client_lock);
583 	adf_attachment_list_to_array(dev, &dev->attach_allowed, attachments,
584 			n_attachments);
585 	retval = dev->n_attach_allowed;
586 	mutex_unlock(&dev->client_lock);
587 
588 	return retval;
589 }
590 EXPORT_SYMBOL(adf_device_attachments_allowed);
591 
592 /**
593  * adf_device_attached - return whether an overlay engine and interface are
594  * attached
595  *
596  * @dev: the parent device
597  * @eng: the overlay engine
598  * @intf: the interface
599  */
adf_device_attached(struct adf_device * dev,struct adf_overlay_engine * eng,struct adf_interface * intf)600 bool adf_device_attached(struct adf_device *dev, struct adf_overlay_engine *eng,
601 		struct adf_interface *intf)
602 {
603 	struct adf_attachment_list *attachment;
604 
605 	mutex_lock(&dev->client_lock);
606 	attachment = adf_attachment_find(&dev->attached, eng, intf);
607 	mutex_unlock(&dev->client_lock);
608 
609 	return attachment != NULL;
610 }
611 EXPORT_SYMBOL(adf_device_attached);
612 
613 /**
614  * adf_device_attach_allowed - return whether the ADF device supports attaching
615  * an overlay engine and interface
616  *
617  * @dev: the parent device
618  * @eng: the overlay engine
619  * @intf: the interface
620  */
adf_device_attach_allowed(struct adf_device * dev,struct adf_overlay_engine * eng,struct adf_interface * intf)621 bool adf_device_attach_allowed(struct adf_device *dev,
622 		struct adf_overlay_engine *eng, struct adf_interface *intf)
623 {
624 	struct adf_attachment_list *attachment;
625 
626 	mutex_lock(&dev->client_lock);
627 	attachment = adf_attachment_find(&dev->attach_allowed, eng, intf);
628 	mutex_unlock(&dev->client_lock);
629 
630 	return attachment != NULL;
631 }
632 EXPORT_SYMBOL(adf_device_attach_allowed);
633 /**
634  * adf_device_attach - attach an overlay engine to an interface
635  *
636  * @dev: the parent device
637  * @eng: the overlay engine
638  * @intf: the interface
639  *
640  * Returns 0 on success, -%EINVAL if attaching @intf and @eng is not allowed,
641  * -%EALREADY if @intf and @eng are already attached, or -errno on any other
642  * failure.
643  */
adf_device_attach(struct adf_device * dev,struct adf_overlay_engine * eng,struct adf_interface * intf)644 int adf_device_attach(struct adf_device *dev, struct adf_overlay_engine *eng,
645 		struct adf_interface *intf)
646 {
647 	int ret;
648 	struct adf_attachment_list *attachment = NULL;
649 
650 	ret = adf_attachment_validate(dev, eng, intf);
651 	if (ret < 0)
652 		return ret;
653 
654 	mutex_lock(&dev->client_lock);
655 
656 	if (dev->n_attached == ADF_MAX_ATTACHMENTS) {
657 		ret = -ENOMEM;
658 		goto done;
659 	}
660 
661 	if (!adf_attachment_find(&dev->attach_allowed, eng, intf)) {
662 		ret = -EINVAL;
663 		goto done;
664 	}
665 
666 	if (adf_attachment_find(&dev->attached, eng, intf)) {
667 		ret = -EALREADY;
668 		goto done;
669 	}
670 
671 	ret = adf_device_attach_op(dev, eng, intf);
672 	if (ret < 0)
673 		goto done;
674 
675 	attachment = kzalloc(sizeof(*attachment), GFP_KERNEL);
676 	if (!attachment) {
677 		ret = -ENOMEM;
678 		goto done;
679 	}
680 
681 	attachment->attachment.interface = intf;
682 	attachment->attachment.overlay_engine = eng;
683 	list_add_tail(&attachment->head, &dev->attached);
684 	dev->n_attached++;
685 
686 done:
687 	mutex_unlock(&dev->client_lock);
688 	if (ret < 0)
689 		kfree(attachment);
690 
691 	return ret;
692 }
693 EXPORT_SYMBOL(adf_device_attach);
694 
695 /**
696  * adf_device_detach - detach an overlay engine from an interface
697  *
698  * @dev: the parent device
699  * @eng: the overlay engine
700  * @intf: the interface
701  *
702  * Returns 0 on success, -%EINVAL if @intf and @eng are not attached,
703  * or -errno on any other failure.
704  */
adf_device_detach(struct adf_device * dev,struct adf_overlay_engine * eng,struct adf_interface * intf)705 int adf_device_detach(struct adf_device *dev, struct adf_overlay_engine *eng,
706 		struct adf_interface *intf)
707 {
708 	int ret;
709 	struct adf_attachment_list *attachment;
710 
711 	ret = adf_attachment_validate(dev, eng, intf);
712 	if (ret < 0)
713 		return ret;
714 
715 	mutex_lock(&dev->client_lock);
716 
717 	attachment = adf_attachment_find(&dev->attached, eng, intf);
718 	if (!attachment) {
719 		ret = -EINVAL;
720 		goto done;
721 	}
722 
723 	ret = adf_device_detach_op(dev, eng, intf);
724 	if (ret < 0)
725 		goto done;
726 
727 	adf_attachment_free(attachment);
728 	dev->n_attached--;
729 done:
730 	mutex_unlock(&dev->client_lock);
731 	return ret;
732 }
733 EXPORT_SYMBOL(adf_device_detach);
734 
735 /**
736  * adf_interface_simple_buffer_alloc - allocate a simple buffer
737  *
738  * @intf: target interface
739  * @w: width in pixels
740  * @h: height in pixels
741  * @format: format fourcc
742  * @dma_buf: returns the allocated buffer
743  * @offset: returns the byte offset of the allocated buffer's first pixel
744  * @pitch: returns the allocated buffer's pitch
745  *
746  * See &struct adf_simple_buffer_alloc for a description of simple buffers and
747  * their limitations.
748  *
749  * Returns 0 on success or -errno on failure.
750  */
adf_interface_simple_buffer_alloc(struct adf_interface * intf,u16 w,u16 h,u32 format,struct dma_buf ** dma_buf,u32 * offset,u32 * pitch)751 int adf_interface_simple_buffer_alloc(struct adf_interface *intf, u16 w, u16 h,
752 		u32 format, struct dma_buf **dma_buf, u32 *offset, u32 *pitch)
753 {
754 	if (!intf->ops || !intf->ops->alloc_simple_buffer)
755 		return -EOPNOTSUPP;
756 
757 	if (!adf_format_is_rgb(format))
758 		return -EINVAL;
759 
760 	return intf->ops->alloc_simple_buffer(intf, w, h, format, dma_buf,
761 			offset, pitch);
762 }
763 EXPORT_SYMBOL(adf_interface_simple_buffer_alloc);
764 
765 /**
766  * adf_interface_simple_post - flip to a single buffer
767  *
768  * @intf: interface targeted by the flip
769  * @buf: buffer to display
770  *
771  * adf_interface_simple_post() can be used generically for simple display
772  * configurations, since the client does not need to provide any driver-private
773  * configuration data.
774  *
775  * adf_interface_simple_post() has the same copying semantics as
776  * adf_device_post().
777  *
778  * On success, returns a sync fence which signals when the buffer is removed
779  * from the screen.  On failure, returns ERR_PTR(-errno).
780  */
adf_interface_simple_post(struct adf_interface * intf,struct adf_buffer * buf)781 struct sync_fence *adf_interface_simple_post(struct adf_interface *intf,
782 		struct adf_buffer *buf)
783 {
784 	size_t custom_data_size = 0;
785 	void *custom_data = NULL;
786 	struct sync_fence *ret;
787 
788 	if (intf->ops && intf->ops->describe_simple_post) {
789 		int err;
790 
791 		custom_data = kzalloc(ADF_MAX_CUSTOM_DATA_SIZE, GFP_KERNEL);
792 		if (!custom_data) {
793 			ret = ERR_PTR(-ENOMEM);
794 			goto done;
795 		}
796 
797 		err = intf->ops->describe_simple_post(intf, buf, custom_data,
798 				&custom_data_size);
799 		if (err < 0) {
800 			ret = ERR_PTR(err);
801 			goto done;
802 		}
803 	}
804 
805 	ret = adf_device_post(adf_interface_parent(intf), &intf, 1, buf, 1,
806 			custom_data, custom_data_size);
807 done:
808 	kfree(custom_data);
809 	return ret;
810 }
811 EXPORT_SYMBOL(adf_interface_simple_post);
812