File Index
Files and directories
Sign in
FILE

msm_gem_prime.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/msm/msm_gem_prime.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright (C) 2013 Red Hat
  4 * Author: Rob Clark <robdclark@gmail.com>
  5 */
  6
  7#include <linux/dma-buf.h>
  8
  9#include <drm/drm_drv.h>
 10#include <drm/drm_prime.h>
 11
 12#include "msm_drv.h"
 13#include "msm_gem.h"
 14
 15struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj)
 16{
 17	struct msm_gem_object *msm_obj = to_msm_bo(obj);
 18	size_t npages = obj->size >> PAGE_SHIFT;
 19
 20	if (msm_obj->flags & MSM_BO_NO_SHARE)
 21		return ERR_PTR(-EINVAL);
 22
 23	if (WARN_ON(!msm_obj->pages))  /* should have already pinned! */
 24		return ERR_PTR(-ENOMEM);
 25
 26	return drm_prime_pages_to_sg(obj->dev, msm_obj->pages, npages);
 27}
 28
 29int msm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map)
 30{
 31	void *vaddr;
 32
 33	vaddr = msm_gem_get_vaddr_locked(obj);
 34	if (IS_ERR(vaddr))
 35		return PTR_ERR(vaddr);
 36	iosys_map_set_vaddr(map, vaddr);
 37
 38	return 0;
 39}
 40
 41void msm_gem_prime_vunmap(struct drm_gem_object *obj, struct iosys_map *map)
 42{
 43	msm_gem_put_vaddr_locked(obj);
 44}
 45
 46static void msm_gem_dmabuf_release(struct dma_buf *dma_buf)
 47{
 48	struct drm_gem_object *obj = dma_buf->priv;
 49
 50	msm_gem_vma_put(obj);
 51	drm_gem_dmabuf_release(dma_buf);
 52}
 53
 54static const struct dma_buf_ops msm_gem_prime_dmabuf_ops =  {
 55	.attach = drm_gem_map_attach,
 56	.detach = drm_gem_map_detach,
 57	.map_dma_buf = drm_gem_map_dma_buf,
 58	.unmap_dma_buf = drm_gem_unmap_dma_buf,
 59	.release = msm_gem_dmabuf_release,
 60	.mmap = drm_gem_dmabuf_mmap,
 61	.vmap = drm_gem_dmabuf_vmap,
 62	.vunmap = drm_gem_dmabuf_vunmap,
 63};
 64
 65struct drm_gem_object *msm_gem_prime_import(struct drm_device *dev,
 66					    struct dma_buf *buf)
 67{
 68	if (buf->ops == &msm_gem_prime_dmabuf_ops) {
 69		struct drm_gem_object *obj = buf->priv;
 70		if (obj->dev == dev) {
 71			/*
 72			 * Importing dmabuf exported from our own gem increases
 73			 * refcount on gem itself instead of f_count of dmabuf.
 74			 */
 75			drm_gem_object_get(obj);
 76			return obj;
 77		}
 78	}
 79
 80	return drm_gem_prime_import(dev, buf);
 81}
 82
 83struct drm_gem_object *msm_gem_prime_import_sg_table(struct drm_device *dev,
 84		struct dma_buf_attachment *attach, struct sg_table *sg)
 85{
 86	return msm_gem_import(dev, attach->dmabuf, sg);
 87}
 88
 89struct dma_buf *msm_gem_prime_export(struct drm_gem_object *obj, int flags)
 90{
 91	if (to_msm_bo(obj)->flags & MSM_BO_NO_SHARE)
 92		return ERR_PTR(-EPERM);
 93
 94	msm_gem_vma_get(obj);
 95
 96	struct drm_device *dev = obj->dev;
 97	struct dma_buf_export_info exp_info = {
 98		.exp_name = KBUILD_MODNAME, /* white lie for debug */
 99		.owner = dev->driver->fops->owner,
100		.ops = &msm_gem_prime_dmabuf_ops,
101		.size = obj->size,
102		.flags = flags,
103		.priv = obj,
104		.resv = obj->resv,
105	};
106
107	return drm_gem_dmabuf_export(dev, &exp_info);
108}
109
110int msm_gem_prime_pin(struct drm_gem_object *obj)
111{
112	struct page **pages;
113	int ret = 0;
114
115	if (drm_gem_is_imported(obj))
116		return 0;
117
118	if (to_msm_bo(obj)->flags & MSM_BO_NO_SHARE)
119		return -EINVAL;
120
121	pages = msm_gem_pin_pages_locked(obj);
122	if (IS_ERR(pages))
123		ret = PTR_ERR(pages);
124
125	return ret;
126}
127
128void msm_gem_prime_unpin(struct drm_gem_object *obj)
129{
130	if (drm_gem_is_imported(obj))
131		return;
132
133	msm_gem_unpin_pages_locked(obj);
134}
~/ Read-only file preview.