Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
gpu
drm
exynos
exynos_drm_buf.c
Go to the documentation of this file.
1
/* exynos_drm_buf.c
2
*
3
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
4
* Author: Inki Dae <
[email protected]
>
5
*
6
* Permission is hereby granted, free of charge, to any person obtaining a
7
* copy of this software and associated documentation files (the "Software"),
8
* to deal in the Software without restriction, including without limitation
9
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
* and/or sell copies of the Software, and to permit persons to whom the
11
* Software is furnished to do so, subject to the following conditions:
12
*
13
* The above copyright notice and this permission notice (including the next
14
* paragraph) shall be included in all copies or substantial portions of the
15
* Software.
16
*
17
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
* OTHER DEALINGS IN THE SOFTWARE.
24
*/
25
26
#include <
drm/drmP.h
>
27
#include <drm/exynos_drm.h>
28
29
#include "
exynos_drm_drv.h
"
30
#include "
exynos_drm_gem.h
"
31
#include "
exynos_drm_buf.h
"
32
33
static
int
lowlevel_buffer_allocate(
struct
drm_device
*
dev
,
34
unsigned
int
flags
,
struct
exynos_drm_gem_buf
*
buf
)
35
{
36
dma_addr_t
start_addr
;
37
unsigned
int
npages,
i
= 0;
38
struct
scatterlist
*
sgl
;
39
int
ret
= 0;
40
41
DRM_DEBUG_KMS(
"%s\n"
, __FILE__);
42
43
if
(
IS_NONCONTIG_BUFFER
(flags)) {
44
DRM_DEBUG_KMS(
"not support allocation type.\n"
);
45
return
-
EINVAL
;
46
}
47
48
if
(buf->
dma_addr
) {
49
DRM_DEBUG_KMS(
"already allocated.\n"
);
50
return
0;
51
}
52
53
if
(buf->
size
>=
SZ_1M
) {
54
npages = buf->
size
>>
SECTION_SHIFT
;
55
buf->
page_size
=
SECTION_SIZE
;
56
}
else
if
(buf->
size
>=
SZ_64K
) {
57
npages = buf->
size
>> 16;
58
buf->
page_size
=
SZ_64K
;
59
}
else
{
60
npages = buf->
size
>>
PAGE_SHIFT
;
61
buf->
page_size
=
PAGE_SIZE
;
62
}
63
64
buf->
sgt
= kzalloc(
sizeof
(
struct
sg_table
),
GFP_KERNEL
);
65
if
(!buf->
sgt
) {
66
DRM_ERROR(
"failed to allocate sg table.\n"
);
67
return
-
ENOMEM
;
68
}
69
70
ret =
sg_alloc_table
(buf->
sgt
, npages,
GFP_KERNEL
);
71
if
(ret < 0) {
72
DRM_ERROR(
"failed to initialize sg table.\n"
);
73
kfree
(buf->
sgt
);
74
buf->
sgt
=
NULL
;
75
return
-
ENOMEM
;
76
}
77
78
buf->
kvaddr
=
dma_alloc_writecombine
(dev->dev, buf->
size
,
79
&buf->
dma_addr
,
GFP_KERNEL
);
80
if
(!buf->
kvaddr
) {
81
DRM_ERROR(
"failed to allocate buffer.\n"
);
82
ret = -
ENOMEM
;
83
goto
err1;
84
}
85
86
buf->
pages
= kzalloc(
sizeof
(
struct
page
) * npages,
GFP_KERNEL
);
87
if
(!buf->
pages
) {
88
DRM_ERROR(
"failed to allocate pages.\n"
);
89
ret = -
ENOMEM
;
90
goto
err2;
91
}
92
93
sgl = buf->
sgt
->sgl;
94
start_addr = buf->
dma_addr
;
95
96
while
(i < npages) {
97
buf->
pages
[
i
] =
phys_to_page
(start_addr);
98
sg_set_page(sgl, buf->
pages
[i], buf->
page_size
, 0);
99
sg_dma_address
(sgl) =
start_addr
;
100
start_addr += buf->
page_size
;
101
sgl =
sg_next
(sgl);
102
i++;
103
}
104
105
DRM_DEBUG_KMS(
"vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n"
,
106
(
unsigned
long
)buf->
kvaddr
,
107
(
unsigned
long
)buf->
dma_addr
,
108
buf->
size
);
109
110
return
ret
;
111
err2:
112
dma_free_writecombine
(dev->dev, buf->
size
, buf->
kvaddr
,
113
(
dma_addr_t
)buf->
dma_addr
);
114
buf->
dma_addr
= (
dma_addr_t
)
NULL
;
115
err1:
116
sg_free_table
(buf->
sgt
);
117
kfree
(buf->
sgt
);
118
buf->
sgt
=
NULL
;
119
120
return
ret
;
121
}
122
123
static
void
lowlevel_buffer_deallocate(
struct
drm_device
*dev,
124
unsigned
int
flags,
struct
exynos_drm_gem_buf
*buf)
125
{
126
DRM_DEBUG_KMS(
"%s.\n"
, __FILE__);
127
128
/*
129
* release only physically continuous memory and
130
* non-continuous memory would be released by exynos
131
* gem framework.
132
*/
133
if
(
IS_NONCONTIG_BUFFER
(flags)) {
134
DRM_DEBUG_KMS(
"not support allocation type.\n"
);
135
return
;
136
}
137
138
if
(!buf->
dma_addr
) {
139
DRM_DEBUG_KMS(
"dma_addr is invalid.\n"
);
140
return
;
141
}
142
143
DRM_DEBUG_KMS(
"vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n"
,
144
(
unsigned
long
)buf->
kvaddr
,
145
(
unsigned
long
)buf->
dma_addr
,
146
buf->
size
);
147
148
sg_free_table
(buf->
sgt
);
149
150
kfree
(buf->
sgt
);
151
buf->
sgt
=
NULL
;
152
153
kfree
(buf->
pages
);
154
buf->
pages
=
NULL
;
155
156
dma_free_writecombine
(dev->dev, buf->
size
, buf->
kvaddr
,
157
(
dma_addr_t
)buf->
dma_addr
);
158
buf->
dma_addr
= (
dma_addr_t
)
NULL
;
159
}
160
161
struct
exynos_drm_gem_buf
*
exynos_drm_init_buf
(
struct
drm_device
*dev,
162
unsigned
int
size
)
163
{
164
struct
exynos_drm_gem_buf
*
buffer
;
165
166
DRM_DEBUG_KMS(
"%s.\n"
, __FILE__);
167
DRM_DEBUG_KMS(
"desired size = 0x%x\n"
, size);
168
169
buffer = kzalloc(
sizeof
(*buffer),
GFP_KERNEL
);
170
if
(!buffer) {
171
DRM_ERROR(
"failed to allocate exynos_drm_gem_buf.\n"
);
172
return
NULL
;
173
}
174
175
buffer->
size
=
size
;
176
return
buffer
;
177
}
178
179
void
exynos_drm_fini_buf
(
struct
drm_device
*dev,
180
struct
exynos_drm_gem_buf
*
buffer
)
181
{
182
DRM_DEBUG_KMS(
"%s.\n"
, __FILE__);
183
184
if
(!buffer) {
185
DRM_DEBUG_KMS(
"buffer is null.\n"
);
186
return
;
187
}
188
189
kfree
(buffer);
190
buffer =
NULL
;
191
}
192
193
int
exynos_drm_alloc_buf
(
struct
drm_device
*dev,
194
struct
exynos_drm_gem_buf
*buf,
unsigned
int
flags)
195
{
196
197
/*
198
* allocate memory region and set the memory information
199
* to vaddr and dma_addr of a buffer object.
200
*/
201
if
(lowlevel_buffer_allocate(dev, flags, buf) < 0)
202
return
-
ENOMEM
;
203
204
return
0;
205
}
206
207
void
exynos_drm_free_buf
(
struct
drm_device
*dev,
208
unsigned
int
flags,
struct
exynos_drm_gem_buf
*
buffer
)
209
{
210
211
lowlevel_buffer_deallocate(dev, flags, buffer);
212
}
Generated on Thu Jan 10 2013 13:31:19 for Linux Kernel by
1.8.2