forked from teddywlq/smifb2
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsmi_prime.c
More file actions
123 lines (97 loc) · 2.59 KB
/
smi_prime.c
File metadata and controls
123 lines (97 loc) · 2.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// SPDX-License-Identifier: GPL-2.0+
// Copyright (c) 2023, SiliconMotion Inc.
#include "smi_dbg.h"
#include "smi_drv.h"
#include <linux/dma-buf.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)
#include <drm/drmP.h>
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 3, 0)
struct sg_table *smi_gem_prime_get_sg_table(struct drm_gem_object *obj)
{
struct smi_bo *bo = gem_to_smi_bo(obj);
int npages = bo->bo.num_pages;
return drm_prime_pages_to_sg(bo->bo.ttm->pages, npages);
}
void *smi_gem_prime_vmap(struct drm_gem_object *obj)
{
struct smi_bo *bo = gem_to_smi_bo(obj);
int ret;
void *base;
ret = smi_bo_pin(bo, TTM_PL_FLAG_VRAM, NULL);
if (ret)
return (NULL);
base = smi_bo_kmap(bo, true, NULL);
if (IS_ERR(base)) {
smi_bo_unpin(bo);
return (NULL);
}
return (base);
}
void smi_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
{
struct smi_bo *bo = gem_to_smi_bo(obj);
smi_bo_kunmap(bo);
smi_bo_unpin(bo);
}
int smi_gem_prime_pin(struct drm_gem_object *obj)
{
struct smi_bo *bo = gem_to_smi_bo(obj);
int ret = 0;
ENTER();
/* pin buffer into GTT */
ret = smi_bo_pin(bo, TTM_PL_FLAG_SYSTEM, NULL);
LEAVE(ret);
}
void smi_gem_prime_unpin(struct drm_gem_object *obj)
{
struct smi_bo *bo = gem_to_smi_bo(obj);
smi_bo_unpin(bo);
}
#else
static const struct drm_gem_object_funcs smi_gem_object_funcs = {
.free = smi_gem_free_object,
};
#endif
struct drm_gem_object *smi_gem_prime_import_sg_table(struct drm_device *dev,
struct dma_buf_attachment *attach,
struct sg_table *sg)
{
struct smi_device *UNUSED(sdev) = dev->dev_private;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
struct drm_gem_vram_object *gbo;
#else
struct smi_bo *bo;
#endif
int ret = 0;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
gbo = drm_gem_vram_create(dev, attach->dmabuf->size, PAGE_SIZE);
#else
gbo = drm_gem_vram_create(dev, &dev->vram_mm->bdev, attach->dmabuf->size, PAGE_SIZE, false);
#endif
if (IS_ERR(gbo)) {
ret = PTR_ERR(gbo);
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
gbo->bo.base.funcs = &smi_gem_object_funcs;
#else
gbo->gem.funcs = &smi_gem_object_funcs;
#endif
#else
struct reservation_object *resv = attach->dmabuf->resv;
ww_mutex_lock(&resv->lock, NULL);
ret = smi_bo_create(dev, attach->dmabuf->size, PAGE_SIZE, 0, sg, resv, &bo);
ww_mutex_unlock(&resv->lock);
#endif
if (ret) {
return (ERR_PTR(ret));
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
return (&gbo->bo.base);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
return (&gbo->gem);
#else
return (&bo->gem);
#endif
}