Skip to content

Commit

Permalink
drm/tegra: Implement new UAPI
Browse files Browse the repository at this point in the history
Implement the non-submission parts of the new UAPI, including
channel management and memory mapping. The UAPI is under the
CONFIG_DRM_TEGRA_STAGING config flag for now.

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
  • Loading branch information
cyndis authored and intel-lab-lkp committed Jan 11, 2021
1 parent ed10454 commit 2c6bdcf
Show file tree
Hide file tree
Showing 5 changed files with 401 additions and 16 deletions.
1 change: 1 addition & 0 deletions drivers/gpu/drm/tegra/Makefile
Expand Up @@ -3,6 +3,7 @@ ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG

tegra-drm-y := \
drm.o \
uapi/uapi.o \
gem.o \
fb.o \
dp.o \
Expand Down
41 changes: 25 additions & 16 deletions drivers/gpu/drm/tegra/drm.c
Expand Up @@ -20,6 +20,7 @@
#include <drm/drm_prime.h>
#include <drm/drm_vblank.h>

#include "uapi.h"
#include "drm.h"
#include "gem.h"

Expand All @@ -33,11 +34,6 @@
#define CARVEOUT_SZ SZ_64M
#define CDMA_GATHER_FETCHES_MAX_NB 16383

struct tegra_drm_file {
struct idr contexts;
struct mutex lock;
};

static int tegra_atomic_check(struct drm_device *drm,
struct drm_atomic_state *state)
{
Expand Down Expand Up @@ -90,7 +86,8 @@ static int tegra_drm_open(struct drm_device *drm, struct drm_file *filp)
if (!fpriv)
return -ENOMEM;

idr_init_base(&fpriv->contexts, 1);
idr_init_base(&fpriv->legacy_contexts, 1);
xa_init_flags(&fpriv->contexts, XA_FLAGS_ALLOC1);
mutex_init(&fpriv->lock);
filp->driver_priv = fpriv;

Expand Down Expand Up @@ -429,7 +426,7 @@ static int tegra_client_open(struct tegra_drm_file *fpriv,
if (err < 0)
return err;

err = idr_alloc(&fpriv->contexts, context, 1, 0, GFP_KERNEL);
err = idr_alloc(&fpriv->legacy_contexts, context, 1, 0, GFP_KERNEL);
if (err < 0) {
client->ops->close_channel(context);
return err;
Expand Down Expand Up @@ -484,13 +481,13 @@ static int tegra_close_channel(struct drm_device *drm, void *data,

mutex_lock(&fpriv->lock);

context = idr_find(&fpriv->contexts, args->context);
context = idr_find(&fpriv->legacy_contexts, args->context);
if (!context) {
err = -EINVAL;
goto unlock;
}

idr_remove(&fpriv->contexts, context->id);
idr_remove(&fpriv->legacy_contexts, context->id);
tegra_drm_context_free(context);

unlock:
Expand All @@ -509,7 +506,7 @@ static int tegra_get_syncpt(struct drm_device *drm, void *data,

mutex_lock(&fpriv->lock);

context = idr_find(&fpriv->contexts, args->context);
context = idr_find(&fpriv->legacy_contexts, args->context);
if (!context) {
err = -ENODEV;
goto unlock;
Expand Down Expand Up @@ -538,7 +535,7 @@ static int tegra_submit(struct drm_device *drm, void *data,

mutex_lock(&fpriv->lock);

context = idr_find(&fpriv->contexts, args->context);
context = idr_find(&fpriv->legacy_contexts, args->context);
if (!context) {
err = -ENODEV;
goto unlock;
Expand All @@ -563,7 +560,7 @@ static int tegra_get_syncpt_base(struct drm_device *drm, void *data,

mutex_lock(&fpriv->lock);

context = idr_find(&fpriv->contexts, args->context);
context = idr_find(&fpriv->legacy_contexts, args->context);
if (!context) {
err = -ENODEV;
goto unlock;
Expand Down Expand Up @@ -732,10 +729,21 @@ static int tegra_gem_get_flags(struct drm_device *drm, void *data,

static const struct drm_ioctl_desc tegra_drm_ioctls[] = {
#ifdef CONFIG_DRM_TEGRA_STAGING
DRM_IOCTL_DEF_DRV(TEGRA_GEM_CREATE, tegra_gem_create,
DRM_IOCTL_DEF_DRV(TEGRA_CHANNEL_OPEN, tegra_drm_ioctl_channel_open,
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(TEGRA_CHANNEL_CLOSE, tegra_drm_ioctl_channel_close,
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(TEGRA_CHANNEL_MAP, tegra_drm_ioctl_channel_map,
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(TEGRA_GEM_MMAP, tegra_gem_mmap,
DRM_IOCTL_DEF_DRV(TEGRA_CHANNEL_UNMAP, tegra_drm_ioctl_channel_unmap,
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(TEGRA_GEM_CREATE, tegra_drm_ioctl_gem_create,
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(TEGRA_GEM_MMAP, tegra_drm_ioctl_gem_mmap,
DRM_RENDER_ALLOW),

DRM_IOCTL_DEF_DRV(TEGRA_GEM_CREATE_LEGACY, tegra_gem_create, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(TEGRA_GEM_MMAP_LEGACY, tegra_gem_mmap, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_READ, tegra_syncpt_read,
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_INCR, tegra_syncpt_incr,
Expand Down Expand Up @@ -789,10 +797,11 @@ static void tegra_drm_postclose(struct drm_device *drm, struct drm_file *file)
struct tegra_drm_file *fpriv = file->driver_priv;

mutex_lock(&fpriv->lock);
idr_for_each(&fpriv->contexts, tegra_drm_context_cleanup, NULL);
idr_for_each(&fpriv->legacy_contexts, tegra_drm_context_cleanup, NULL);
tegra_drm_uapi_close_file(fpriv);
mutex_unlock(&fpriv->lock);

idr_destroy(&fpriv->contexts);
idr_destroy(&fpriv->legacy_contexts);
mutex_destroy(&fpriv->lock);
kfree(fpriv);
}
Expand Down
5 changes: 5 additions & 0 deletions drivers/gpu/drm/tegra/drm.h
Expand Up @@ -59,6 +59,11 @@ struct tegra_drm {
struct tegra_display_hub *hub;
};

static inline struct host1x *tegra_drm_to_host1x(struct tegra_drm *tegra)
{
return dev_get_drvdata(tegra->drm->dev->parent);
}

struct tegra_drm_client;

struct tegra_drm_context {
Expand Down
63 changes: 63 additions & 0 deletions drivers/gpu/drm/tegra/uapi.h
@@ -0,0 +1,63 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2020 NVIDIA Corporation */

#ifndef _TEGRA_DRM_UAPI_H
#define _TEGRA_DRM_UAPI_H

#include <linux/dma-mapping.h>
#include <linux/idr.h>
#include <linux/kref.h>
#include <linux/xarray.h>

#include <drm/drm.h>

struct drm_file;
struct drm_device;

struct tegra_drm_file {
/* Legacy UAPI state */
struct idr legacy_contexts;
struct mutex lock;

/* New UAPI state */
struct xarray contexts;
};

struct tegra_drm_channel_ctx {
struct tegra_drm_client *client;
struct host1x_channel *channel;
struct xarray mappings;
};

struct tegra_drm_mapping {
struct kref ref;

struct device *dev;
struct host1x_bo *bo;
struct sg_table *sgt;
enum dma_data_direction direction;
dma_addr_t iova;
dma_addr_t iova_end;
};

int tegra_drm_ioctl_channel_open(struct drm_device *drm, void *data,
struct drm_file *file);
int tegra_drm_ioctl_channel_close(struct drm_device *drm, void *data,
struct drm_file *file);
int tegra_drm_ioctl_channel_map(struct drm_device *drm, void *data,
struct drm_file *file);
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_gem_create(struct drm_device *drm, void *data,
struct drm_file *file);
int tegra_drm_ioctl_gem_mmap(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);
struct tegra_drm_channel_ctx *
tegra_drm_channel_ctx_lock(struct tegra_drm_file *file, u32 id);

#endif

0 comments on commit 2c6bdcf

Please sign in to comment.