Commit fc348336 authored by Mikko Perttunen's avatar Mikko Perttunen Committed by Thierry Reding

drm/tegra: Implement syncpoint management UAPI

Implement TegraDRM IOCTLs for allocating and freeing syncpoints.
Signed-off-by: default avatarMikko Perttunen <mperttunen@nvidia.com>
Signed-off-by: default avatarThierry Reding <treding@nvidia.com>
parent d7c591bc
......@@ -92,6 +92,7 @@ static int tegra_drm_open(struct drm_device *drm, struct drm_file *filp)
idr_init_base(&fpriv->legacy_contexts, 1);
xa_init_flags(&fpriv->contexts, XA_FLAGS_ALLOC1);
xa_init(&fpriv->syncpoints);
mutex_init(&fpriv->lock);
filp->driver_priv = fpriv;
......@@ -727,6 +728,10 @@ static const struct drm_ioctl_desc tegra_drm_ioctls[] = {
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(TEGRA_CHANNEL_UNMAP, tegra_drm_ioctl_channel_unmap,
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(TEGRA_SYNCPOINT_ALLOCATE, tegra_drm_ioctl_syncpoint_allocate,
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(TEGRA_SYNCPOINT_FREE, tegra_drm_ioctl_syncpoint_free,
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(TEGRA_GEM_CREATE, tegra_gem_create, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(TEGRA_GEM_MMAP, tegra_gem_mmap, DRM_RENDER_ALLOW),
......
......@@ -49,12 +49,17 @@ static void tegra_drm_channel_context_close(struct tegra_drm_context *context)
void tegra_drm_uapi_close_file(struct tegra_drm_file *file)
{
struct tegra_drm_context *context;
struct host1x_syncpt *sp;
unsigned long id;
xa_for_each(&file->contexts, id, context)
tegra_drm_channel_context_close(context);
xa_for_each(&file->syncpoints, id, sp)
host1x_syncpt_put(sp);
xa_destroy(&file->contexts);
xa_destroy(&file->syncpoints);
}
static struct tegra_drm_client *tegra_drm_find_client(struct tegra_drm *tegra, u32 class)
......@@ -268,6 +273,50 @@ int tegra_drm_ioctl_channel_unmap(struct drm_device *drm, void *data, struct drm
return 0;
}
int tegra_drm_ioctl_syncpoint_allocate(struct drm_device *drm, void *data, struct drm_file *file)
{
struct host1x *host1x = tegra_drm_to_host1x(drm->dev_private);
struct tegra_drm_file *fpriv = file->driver_priv;
struct drm_tegra_syncpoint_allocate *args = data;
struct host1x_syncpt *sp;
int err;
if (args->id)
return -EINVAL;
sp = host1x_syncpt_alloc(host1x, HOST1X_SYNCPT_CLIENT_MANAGED, current->comm);
if (!sp)
return -EBUSY;
args->id = host1x_syncpt_id(sp);
err = xa_insert(&fpriv->syncpoints, args->id, sp, GFP_KERNEL);
if (err) {
host1x_syncpt_put(sp);
return err;
}
return 0;
}
int tegra_drm_ioctl_syncpoint_free(struct drm_device *drm, void *data, struct drm_file *file)
{
struct tegra_drm_file *fpriv = file->driver_priv;
struct drm_tegra_syncpoint_allocate *args = data;
struct host1x_syncpt *sp;
mutex_lock(&fpriv->lock);
sp = xa_erase(&fpriv->syncpoints, args->id);
mutex_unlock(&fpriv->lock);
if (!sp)
return -EINVAL;
host1x_syncpt_put(sp);
return 0;
}
int tegra_drm_ioctl_gem_create(struct drm_device *drm, void *data,
struct drm_file *file)
{
......
......@@ -21,6 +21,7 @@ struct tegra_drm_file {
/* New UAPI state */
struct xarray contexts;
struct xarray syncpoints;
};
struct tegra_drm_mapping {
......@@ -44,6 +45,10 @@ int tegra_drm_ioctl_channel_unmap(struct drm_device *drm, void *data,
struct drm_file *file);
int tegra_drm_ioctl_channel_submit(struct drm_device *drm, void *data,
struct drm_file *file);
int tegra_drm_ioctl_syncpoint_allocate(struct drm_device *drm, void *data,
struct drm_file *file);
int tegra_drm_ioctl_syncpoint_free(struct drm_device *drm, void *data,
struct drm_file *file);
void tegra_drm_uapi_close_file(struct tegra_drm_file *file);
void tegra_drm_mapping_put(struct tegra_drm_mapping *mapping);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment