drm: implement video fence ioctl [1/3]

PD#SWPL-124599

Problem:
Unable to obtain video fence.

Solution:
implement video fence ioctl.

Verify:
t3x

Test:
DRM-OSD-65

Change-Id: Idf779bbccc05b08786ffbeebe27cd10aa80be682
Signed-off-by: chen.wang1 <chen.wang1@amlogic.com>
This commit is contained in:
chen.wang1
2023-04-28 03:01:37 +00:00
committed by gerrit autosubmit
parent 061c478f68
commit d6aa321845
5 changed files with 115 additions and 1 deletions
@@ -1,3 +1,4 @@
spi_finalize_current_message
strim
bpf_trace_run8
dma_fence_get_stub
+5 -1
View File
@@ -40,7 +40,7 @@
#include "meson_sysfs.h"
#include "meson_writeback.h"
#include "meson_logo.h"
#include "meson_plane.h"
#include <linux/amlogic/media/osd/osd_logo.h>
#include <linux/amlogic/media/vout/vout_notify.h>
#include <linux/amlogic/cpu_version.h>
@@ -90,6 +90,10 @@ static const struct drm_ioctl_desc meson_ioctls[] = {
#endif
DRM_IOCTL_DEF_DRV(MESON_ASYNC_ATOMIC, meson_async_atomic_ioctl,
DRM_UNLOCKED | DRM_AUTH | DRM_RENDER_ALLOW),
#if IS_ENABLED(CONFIG_SYNC_FILE)
DRM_IOCTL_DEF_DRV(MESON_DMABUF_EXPORT_SYNC_FILE, am_meson_dmabuf_export_sync_file_ioctl,
DRM_MASTER),
#endif
};
DEFINE_DRM_GEM_FOPS(meson_drm_fops);
+67
View File
@@ -4,9 +4,15 @@
*/
#include <linux/types.h>
#include <linux/sync_file.h>
#include <linux/dma-fence.h>
#include <linux/dma-buf.h>
#include <uapi/linux/dma-buf.h>
#include <uapi/linux/magic.h>
#ifdef CONFIG_AMLOGIC_MEDIA_FB
#include <linux/amlogic/media/osd/osd_logo.h>
#endif
#include "meson_plane.h"
#include "meson_crtc.h"
#include "meson_vpu.h"
@@ -125,6 +131,67 @@ static const u32 video_supported_drm_formats[] = {
DRM_FORMAT_VUY888,
};
#if IS_ENABLED(CONFIG_SYNC_FILE)
int am_meson_dmabuf_export_sync_file_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
struct drm_meson_dma_buf_export_sync_file *arg = data;
struct dma_fence *fence = NULL;
struct dma_buf *dmabuf = NULL;
struct sync_file *sync_file;
int fd, ret;
DRM_DEBUG("dmabuf-%px fence-%px", dmabuf, fence);
if (arg->flags & ~DMA_BUF_SYNC_RW)
return -EINVAL;
if ((arg->flags & DMA_BUF_SYNC_RW) == 0)
return -EINVAL;
fd = get_unused_fd_flags(O_CLOEXEC);
if (fd < 0)
return fd;
if (arg->dmabuf_fd <= 0)
return -EINVAL;
dmabuf = dma_buf_get(arg->dmabuf_fd);
if (IS_ERR_OR_NULL(dmabuf))
return -EINVAL;
if (arg->flags & DMA_BUF_SYNC_WRITE) {
//fence = dma_resv_get_singleton_unlocked(dmabuf->resv);
//if (IS_ERR(fence)) {
// ret = PTR_ERR(fence);
// goto err_put_fd;
//}
} else if (arg->flags & DMA_BUF_SYNC_READ) {
fence = dma_resv_get_excl_unlocked(dmabuf->resv);
}
if (!fence)
fence = dma_fence_get_stub();
sync_file = sync_file_create(fence);
dma_fence_put(fence);
dma_buf_put(dmabuf);
if (!sync_file) {
ret = -ENOMEM;
goto err_put_fd;
}
fd_install(fd, sync_file->file);
arg->fd = fd;
DRM_DEBUG("dmabuf-%px fence-%px fd-%d", dmabuf, fence, fd);
return 0;
err_put_fd:
put_unused_fd(fd);
return ret;
}
#endif
static void
meson_plane_position_calc(struct meson_vpu_osd_layer_info *plane_info,
struct drm_plane_state *state,
+5
View File
@@ -11,6 +11,7 @@
#include <drm/drm_plane.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <uapi/amlogic/drm/meson_drm.h>
#include <linux/amlogic/media/vout/vout_notify.h>
#include <linux/amlogic/meson_uvm_core.h>
#include <drm/amlogic/meson_drm_plane.h>
@@ -109,4 +110,8 @@ meson_create_scaling_filter_prop(struct drm_device *dev,
void meson_video_set_vfmmode(struct device_node *of_node,
struct meson_drm *priv);
#if IS_ENABLED(CONFIG_SYNC_FILE)
int am_meson_dmabuf_export_sync_file_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv);
#endif
#endif
+37
View File
@@ -36,9 +36,46 @@ struct drm_meson_gem_create {
__u32 handle;
};
/**
* struct drm_meson_dma_buf_export_sync_file - Get a sync_file from a dma-buf
*
* Userspace can perform a DMA_BUF_IOCTL_EXPORT_SYNC_FILE to retrieve the
* current set of fences on a dma-buf file descriptor as a sync_file. CPU
* waits via poll() or other driver-specific mechanisms typically wait on
* whatever fences are on the dma-buf at the time the wait begins. This
* is similar except that it takes a snapshot of the current fences on the
* dma-buf for waiting later instead of waiting immediately. This is
* useful for modern graphics APIs such as Vulkan which assume an explicit
* synchronization model but still need to inter-operate with dma-buf.
*/
struct drm_meson_dma_buf_export_sync_file {
/**
* @flags: Read/write flags
*
* Must be DMA_BUF_SYNC_READ, DMA_BUF_SYNC_WRITE, or both.
*
* If DMA_BUF_SYNC_READ is set and DMA_BUF_SYNC_WRITE is not set,
* the returned sync file waits on any writers of the dma-buf to
* complete. Waiting on the returned sync file is equivalent to
* poll() with POLLIN.
*
* If DMA_BUF_SYNC_WRITE is set, the returned sync file waits on
* any users of the dma-buf (read or write) to complete. Waiting
* on the returned sync file is equivalent to poll() with POLLOUT.
* If both DMA_BUF_SYNC_WRITE and DMA_BUF_SYNC_READ are set, this
* is equivalent to just DMA_BUF_SYNC_WRITE.
*/
__u32 flags;
__u32 dmabuf_fd;
/** @fd: Returned sync file descriptor */
__s32 fd;
};
/*Memory related.*/
#define DRM_IOCTL_MESON_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + \
0x00, struct drm_meson_gem_create)
#define DRM_IOCTL_MESON_DMABUF_EXPORT_SYNC_FILE DRM_IOWR(DRM_COMMAND_BASE + \
0x02, struct drm_meson_dma_buf_export_sync_file)
/*KMS related.*/
#define DRM_IOCTL_MESON_ASYNC_ATOMIC DRM_IOWR(DRM_COMMAND_BASE + \