[go: nahoru, domu]

1de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen/*
2de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen * NVIDIA Tegra DRM GEM helper functions
3de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen *
4de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen * Copyright (C) 2012 Sascha Hauer, Pengutronix
5de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen * Copyright (C) 2013 NVIDIA CORPORATION, All rights reserved.
6de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen *
7de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen * Based on the GEM/CMA helpers
8de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen *
9de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen * Copyright (c) 2011 Samsung Electronics Co., Ltd.
10de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen *
119a2ac2dcdc4baa63c913377f9856993498398025Thierry Reding * This program is free software; you can redistribute it and/or modify
129a2ac2dcdc4baa63c913377f9856993498398025Thierry Reding * it under the terms of the GNU General Public License version 2 as
139a2ac2dcdc4baa63c913377f9856993498398025Thierry Reding * published by the Free Software Foundation.
14de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen */
15de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
163800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding#include <linux/dma-buf.h>
17773af77fc479fd454c3f6836f86bf63996545cf4Thierry Reding#include <drm/tegra_drm.h>
18773af77fc479fd454c3f6836f86bf63996545cf4Thierry Reding
19d1f3e1e0b38d49cbb996dcf0fde5b5205d12a23dThierry Reding#include "drm.h"
20de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen#include "gem.h"
21de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
223be8274341499cfc258eddda29f626d7be10dde5Thierry Redingstatic inline struct tegra_bo *host1x_to_tegra_bo(struct host1x_bo *bo)
23de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{
24de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	return container_of(bo, struct tegra_bo, base);
25de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen}
26de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
27de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenstatic void tegra_bo_put(struct host1x_bo *bo)
28de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{
293be8274341499cfc258eddda29f626d7be10dde5Thierry Reding	struct tegra_bo *obj = host1x_to_tegra_bo(bo);
30de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	struct drm_device *drm = obj->gem.dev;
31de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
32de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	mutex_lock(&drm->struct_mutex);
33de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	drm_gem_object_unreference(&obj->gem);
34de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	mutex_unlock(&drm->struct_mutex);
35de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen}
36de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
37de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenstatic dma_addr_t tegra_bo_pin(struct host1x_bo *bo, struct sg_table **sgt)
38de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{
393be8274341499cfc258eddda29f626d7be10dde5Thierry Reding	struct tegra_bo *obj = host1x_to_tegra_bo(bo);
40de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
41de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	return obj->paddr;
42de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen}
43de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
44de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenstatic void tegra_bo_unpin(struct host1x_bo *bo, struct sg_table *sgt)
45de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{
46de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen}
47de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
48de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenstatic void *tegra_bo_mmap(struct host1x_bo *bo)
49de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{
503be8274341499cfc258eddda29f626d7be10dde5Thierry Reding	struct tegra_bo *obj = host1x_to_tegra_bo(bo);
51de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
52de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	return obj->vaddr;
53de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen}
54de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
55de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenstatic void tegra_bo_munmap(struct host1x_bo *bo, void *addr)
56de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{
57de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen}
58de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
59de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenstatic void *tegra_bo_kmap(struct host1x_bo *bo, unsigned int page)
60de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{
613be8274341499cfc258eddda29f626d7be10dde5Thierry Reding	struct tegra_bo *obj = host1x_to_tegra_bo(bo);
62de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
63de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	return obj->vaddr + page * PAGE_SIZE;
64de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen}
65de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
66de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenstatic void tegra_bo_kunmap(struct host1x_bo *bo, unsigned int page,
67de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen			    void *addr)
68de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{
69de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen}
70de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
71de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenstatic struct host1x_bo *tegra_bo_get(struct host1x_bo *bo)
72de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{
733be8274341499cfc258eddda29f626d7be10dde5Thierry Reding	struct tegra_bo *obj = host1x_to_tegra_bo(bo);
74de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	struct drm_device *drm = obj->gem.dev;
75de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
76de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	mutex_lock(&drm->struct_mutex);
77de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	drm_gem_object_reference(&obj->gem);
78de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	mutex_unlock(&drm->struct_mutex);
79de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
80de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	return bo;
81de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen}
82de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
83425c0fdc427440fdaf039a649eab713d932fa368Thierry Redingstatic const struct host1x_bo_ops tegra_bo_ops = {
84de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	.get = tegra_bo_get,
85de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	.put = tegra_bo_put,
86de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	.pin = tegra_bo_pin,
87de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	.unpin = tegra_bo_unpin,
88de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	.mmap = tegra_bo_mmap,
89de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	.munmap = tegra_bo_munmap,
90de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	.kmap = tegra_bo_kmap,
91de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	.kunmap = tegra_bo_kunmap,
92de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen};
93de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
94de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenstatic void tegra_bo_destroy(struct drm_device *drm, struct tegra_bo *bo)
95de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{
96de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	dma_free_writecombine(drm->dev, bo->gem.size, bo->vaddr, bo->paddr);
97de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen}
98de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
99773af77fc479fd454c3f6836f86bf63996545cf4Thierry Redingstruct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size,
100773af77fc479fd454c3f6836f86bf63996545cf4Thierry Reding				 unsigned long flags)
101de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{
102de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	struct tegra_bo *bo;
103de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	int err;
104de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
105de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	bo = kzalloc(sizeof(*bo), GFP_KERNEL);
106de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	if (!bo)
107de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen		return ERR_PTR(-ENOMEM);
108de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
109de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	host1x_bo_init(&bo->base, &tegra_bo_ops);
110de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	size = round_up(size, PAGE_SIZE);
111de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
112de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	bo->vaddr = dma_alloc_writecombine(drm->dev, size, &bo->paddr,
113de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen					   GFP_KERNEL | __GFP_NOWARN);
114de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	if (!bo->vaddr) {
115de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen		dev_err(drm->dev, "failed to allocate buffer with size %u\n",
116de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen			size);
117de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen		err = -ENOMEM;
118de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen		goto err_dma;
119de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	}
120de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
121de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	err = drm_gem_object_init(drm, &bo->gem, size);
122de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	if (err)
123de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen		goto err_init;
124de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
125de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	err = drm_gem_create_mmap_offset(&bo->gem);
126de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	if (err)
127de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen		goto err_mmap;
128de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
129773af77fc479fd454c3f6836f86bf63996545cf4Thierry Reding	if (flags & DRM_TEGRA_GEM_CREATE_TILED)
130c134f019abcfaa1cb6e07f6154e92a4f8ce8ddd8Thierry Reding		bo->tiling.mode = TEGRA_BO_TILING_MODE_TILED;
131773af77fc479fd454c3f6836f86bf63996545cf4Thierry Reding
132db7fbdfd25ee009165b6c3b80a9d1c6d8534ad94Thierry Reding	if (flags & DRM_TEGRA_GEM_CREATE_BOTTOM_UP)
133db7fbdfd25ee009165b6c3b80a9d1c6d8534ad94Thierry Reding		bo->flags |= TEGRA_BO_BOTTOM_UP;
134db7fbdfd25ee009165b6c3b80a9d1c6d8534ad94Thierry Reding
135de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	return bo;
136de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
137de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenerr_mmap:
138de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	drm_gem_object_release(&bo->gem);
139de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenerr_init:
140de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	tegra_bo_destroy(drm, bo);
141de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenerr_dma:
142de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	kfree(bo);
143de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
144de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	return ERR_PTR(err);
145de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen}
146de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
147de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenstruct tegra_bo *tegra_bo_create_with_handle(struct drm_file *file,
1483be8274341499cfc258eddda29f626d7be10dde5Thierry Reding					     struct drm_device *drm,
1493be8274341499cfc258eddda29f626d7be10dde5Thierry Reding					     unsigned int size,
150773af77fc479fd454c3f6836f86bf63996545cf4Thierry Reding					     unsigned long flags,
1513be8274341499cfc258eddda29f626d7be10dde5Thierry Reding					     unsigned int *handle)
152de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{
153de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	struct tegra_bo *bo;
154de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	int ret;
155de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
156773af77fc479fd454c3f6836f86bf63996545cf4Thierry Reding	bo = tegra_bo_create(drm, size, flags);
157de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	if (IS_ERR(bo))
158de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen		return bo;
159de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
160de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	ret = drm_gem_handle_create(file, &bo->gem, handle);
161de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	if (ret)
162de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen		goto err;
163de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
164de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	drm_gem_object_unreference_unlocked(&bo->gem);
165de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
166de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	return bo;
167de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
168de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenerr:
169de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	tegra_bo_free_object(&bo->gem);
170de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	return ERR_PTR(ret);
171de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen}
172de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
173540457cc1fc14707f60b0eddf9df2904ba75c269Thierry Redingstatic struct tegra_bo *tegra_bo_import(struct drm_device *drm,
174540457cc1fc14707f60b0eddf9df2904ba75c269Thierry Reding					struct dma_buf *buf)
1753800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding{
1763800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	struct dma_buf_attachment *attach;
1773800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	struct tegra_bo *bo;
1783800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	ssize_t size;
1793800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	int err;
1803800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
1813800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	bo = kzalloc(sizeof(*bo), GFP_KERNEL);
1823800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	if (!bo)
1833800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding		return ERR_PTR(-ENOMEM);
1843800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
1853800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	host1x_bo_init(&bo->base, &tegra_bo_ops);
1863800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	size = round_up(buf->size, PAGE_SIZE);
1873800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
1883800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	err = drm_gem_object_init(drm, &bo->gem, size);
1893800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	if (err < 0)
1903800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding		goto free;
1913800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
1923800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	err = drm_gem_create_mmap_offset(&bo->gem);
1933800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	if (err < 0)
1943800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding		goto release;
1953800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
1963800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	attach = dma_buf_attach(buf, drm->dev);
1973800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	if (IS_ERR(attach)) {
1983800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding		err = PTR_ERR(attach);
1993800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding		goto free_mmap;
2003800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	}
2013800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
2023800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	get_dma_buf(buf);
2033800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
2043800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	bo->sgt = dma_buf_map_attachment(attach, DMA_TO_DEVICE);
2053800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	if (!bo->sgt) {
2063800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding		err = -ENOMEM;
2073800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding		goto detach;
2083800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	}
2093800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
2103800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	if (IS_ERR(bo->sgt)) {
2113800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding		err = PTR_ERR(bo->sgt);
2123800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding		goto detach;
2133800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	}
2143800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
2153800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	if (bo->sgt->nents > 1) {
2163800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding		err = -EINVAL;
2173800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding		goto detach;
2183800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	}
2193800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
2203800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	bo->paddr = sg_dma_address(bo->sgt->sgl);
2213800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	bo->gem.import_attach = attach;
2223800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
2233800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	return bo;
2243800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
2253800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingdetach:
2263800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	if (!IS_ERR_OR_NULL(bo->sgt))
2273800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding		dma_buf_unmap_attachment(attach, bo->sgt, DMA_TO_DEVICE);
2283800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
2293800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	dma_buf_detach(buf, attach);
2303800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	dma_buf_put(buf);
2313800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingfree_mmap:
2323800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	drm_gem_free_mmap_offset(&bo->gem);
2333800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingrelease:
2343800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	drm_gem_object_release(&bo->gem);
2353800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingfree:
2363800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	kfree(bo);
2373800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
2383800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	return ERR_PTR(err);
2393800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding}
2403800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
241de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenvoid tegra_bo_free_object(struct drm_gem_object *gem)
242de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{
243de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	struct tegra_bo *bo = to_tegra_bo(gem);
244de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
2453800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	if (gem->import_attach) {
2463800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding		dma_buf_unmap_attachment(gem->import_attach, bo->sgt,
2473800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding					 DMA_TO_DEVICE);
2483800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding		drm_prime_gem_destroy(gem, NULL);
2493800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	} else {
2503800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding		tegra_bo_destroy(gem->dev, bo);
2513800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	}
2523800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
2530de23977cfeb5b357ec884ba15417ae118ff9e9bDavid Herrmann	drm_gem_free_mmap_offset(gem);
254de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	drm_gem_object_release(gem);
255de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
256de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	kfree(bo);
257de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen}
258de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
259de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenint tegra_bo_dumb_create(struct drm_file *file, struct drm_device *drm,
260de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen			 struct drm_mode_create_dumb *args)
261de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{
262de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
263d1f3e1e0b38d49cbb996dcf0fde5b5205d12a23dThierry Reding	struct tegra_drm *tegra = drm->dev_private;
264de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	struct tegra_bo *bo;
265de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
266d1f3e1e0b38d49cbb996dcf0fde5b5205d12a23dThierry Reding	min_pitch = round_up(min_pitch, tegra->pitch_align);
267de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	if (args->pitch < min_pitch)
268de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen		args->pitch = min_pitch;
269de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
270de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	if (args->size < args->pitch * args->height)
271de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen		args->size = args->pitch * args->height;
272de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
273773af77fc479fd454c3f6836f86bf63996545cf4Thierry Reding	bo = tegra_bo_create_with_handle(file, drm, args->size, 0,
2743be8274341499cfc258eddda29f626d7be10dde5Thierry Reding					 &args->handle);
275de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	if (IS_ERR(bo))
276de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen		return PTR_ERR(bo);
277de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
278de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	return 0;
279de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen}
280de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
281de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenint tegra_bo_dumb_map_offset(struct drm_file *file, struct drm_device *drm,
282de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen			     uint32_t handle, uint64_t *offset)
283de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{
284de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	struct drm_gem_object *gem;
285de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	struct tegra_bo *bo;
286de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
287de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	mutex_lock(&drm->struct_mutex);
288de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
289de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	gem = drm_gem_object_lookup(drm, file, handle);
290de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	if (!gem) {
291de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen		dev_err(drm->dev, "failed to lookup GEM object\n");
292de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen		mutex_unlock(&drm->struct_mutex);
293de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen		return -EINVAL;
294de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	}
295de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
296de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	bo = to_tegra_bo(gem);
297de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
2982bc7b0ca8cc3bdcf61a7d4a99ed55c4ad084a4aeDavid Herrmann	*offset = drm_vma_node_offset_addr(&bo->gem.vma_node);
299de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
300de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	drm_gem_object_unreference(gem);
301de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
302de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	mutex_unlock(&drm->struct_mutex);
303de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
304de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	return 0;
305de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen}
306de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
307de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenconst struct vm_operations_struct tegra_bo_vm_ops = {
308de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	.open = drm_gem_vm_open,
309de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	.close = drm_gem_vm_close,
310de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen};
311de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
312de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenint tegra_drm_mmap(struct file *file, struct vm_area_struct *vma)
313de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{
314de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	struct drm_gem_object *gem;
315de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	struct tegra_bo *bo;
316de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	int ret;
317de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
318de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	ret = drm_gem_mmap(file, vma);
319de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	if (ret)
320de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen		return ret;
321de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
322de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	gem = vma->vm_private_data;
323de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	bo = to_tegra_bo(gem);
324de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
325de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	ret = remap_pfn_range(vma, vma->vm_start, bo->paddr >> PAGE_SHIFT,
326de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen			      vma->vm_end - vma->vm_start, vma->vm_page_prot);
327de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	if (ret)
328de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen		drm_gem_vm_close(vma);
329de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen
330de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen	return ret;
331de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen}
3323800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
3333800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingstatic struct sg_table *
3343800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingtegra_gem_prime_map_dma_buf(struct dma_buf_attachment *attach,
3353800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding			    enum dma_data_direction dir)
3363800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding{
3373800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	struct drm_gem_object *gem = attach->dmabuf->priv;
3383800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	struct tegra_bo *bo = to_tegra_bo(gem);
3393800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	struct sg_table *sgt;
3403800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
3413800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
3423800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	if (!sgt)
3433800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding		return NULL;
3443800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
3453800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	if (sg_alloc_table(sgt, 1, GFP_KERNEL)) {
3463800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding		kfree(sgt);
3473800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding		return NULL;
3483800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	}
3493800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
3503800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	sg_dma_address(sgt->sgl) = bo->paddr;
3513800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	sg_dma_len(sgt->sgl) = gem->size;
3523800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
3533800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	return sgt;
3543800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding}
3553800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
3563800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingstatic void tegra_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach,
3573800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding					  struct sg_table *sgt,
3583800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding					  enum dma_data_direction dir)
3593800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding{
3603800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	sg_free_table(sgt);
3613800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	kfree(sgt);
3623800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding}
3633800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
3643800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingstatic void tegra_gem_prime_release(struct dma_buf *buf)
3653800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding{
3663800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	drm_gem_dmabuf_release(buf);
3673800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding}
3683800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
3693800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingstatic void *tegra_gem_prime_kmap_atomic(struct dma_buf *buf,
3703800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding					 unsigned long page)
3713800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding{
3723800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	return NULL;
3733800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding}
3743800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
3753800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingstatic void tegra_gem_prime_kunmap_atomic(struct dma_buf *buf,
3763800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding					  unsigned long page,
3773800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding					  void *addr)
3783800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding{
3793800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding}
3803800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
3813800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingstatic void *tegra_gem_prime_kmap(struct dma_buf *buf, unsigned long page)
3823800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding{
3833800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	return NULL;
3843800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding}
3853800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
3863800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingstatic void tegra_gem_prime_kunmap(struct dma_buf *buf, unsigned long page,
3873800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding				   void *addr)
3883800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding{
3893800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding}
3903800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
3913800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingstatic int tegra_gem_prime_mmap(struct dma_buf *buf, struct vm_area_struct *vma)
3923800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding{
3933800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	return -EINVAL;
3943800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding}
3953800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
396d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Redingstatic void *tegra_gem_prime_vmap(struct dma_buf *buf)
397d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Reding{
398d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Reding	struct drm_gem_object *gem = buf->priv;
399d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Reding	struct tegra_bo *bo = to_tegra_bo(gem);
400d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Reding
401d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Reding	return bo->vaddr;
402d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Reding}
403d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Reding
404d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Redingstatic void tegra_gem_prime_vunmap(struct dma_buf *buf, void *vaddr)
405d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Reding{
406d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Reding}
407d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Reding
4083800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingstatic const struct dma_buf_ops tegra_gem_prime_dmabuf_ops = {
4093800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	.map_dma_buf = tegra_gem_prime_map_dma_buf,
4103800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	.unmap_dma_buf = tegra_gem_prime_unmap_dma_buf,
4113800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	.release = tegra_gem_prime_release,
4123800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	.kmap_atomic = tegra_gem_prime_kmap_atomic,
4133800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	.kunmap_atomic = tegra_gem_prime_kunmap_atomic,
4143800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	.kmap = tegra_gem_prime_kmap,
4153800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	.kunmap = tegra_gem_prime_kunmap,
4163800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	.mmap = tegra_gem_prime_mmap,
417d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Reding	.vmap = tegra_gem_prime_vmap,
418d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Reding	.vunmap = tegra_gem_prime_vunmap,
4193800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding};
4203800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
4213800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingstruct dma_buf *tegra_gem_prime_export(struct drm_device *drm,
4223800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding				       struct drm_gem_object *gem,
4233800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding				       int flags)
4243800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding{
4253800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	return dma_buf_export(gem, &tegra_gem_prime_dmabuf_ops, gem->size,
4263aac4502fd3f80dcf7e65dbf6edd8676893c1f46Maarten Lankhorst			      flags, NULL);
4273800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding}
4283800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
4293800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingstruct drm_gem_object *tegra_gem_prime_import(struct drm_device *drm,
4303800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding					      struct dma_buf *buf)
4313800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding{
4323800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	struct tegra_bo *bo;
4333800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
4343800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	if (buf->ops == &tegra_gem_prime_dmabuf_ops) {
4353800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding		struct drm_gem_object *gem = buf->priv;
4363800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
4373800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding		if (gem->dev == drm) {
4383800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding			drm_gem_object_reference(gem);
4393800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding			return gem;
4403800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding		}
4413800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	}
4423800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
4433800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	bo = tegra_bo_import(drm, buf);
4443800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	if (IS_ERR(bo))
4453800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding		return ERR_CAST(bo);
4463800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding
4473800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding	return &bo->gem;
4483800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding}
449