adf_client.c 20 KB

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