3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * Author: Inki Dae <inki.dae@samsung.com>
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:
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
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.
28 #include "exynos_drm.h"
30 #include "exynos_drm_drv.h"
31 #include "exynos_drm_gem.h"
32 #include "exynos_drm_buf.h"
34 static int lowlevel_buffer_allocate(struct drm_device
*dev
,
35 unsigned int flags
, struct exynos_drm_gem_buf
*buf
)
37 dma_addr_t start_addr
;
38 unsigned int npages
, i
= 0;
39 struct scatterlist
*sgl
;
42 DRM_DEBUG_KMS("%s\n", __FILE__
);
44 if (IS_NONCONTIG_BUFFER(flags
)) {
45 DRM_DEBUG_KMS("not support allocation type.\n");
50 DRM_DEBUG_KMS("already allocated.\n");
54 if (buf
->size
>= SZ_1M
) {
55 npages
= buf
->size
>> SECTION_SHIFT
;
56 buf
->page_size
= SECTION_SIZE
;
57 } else if (buf
->size
>= SZ_64K
) {
58 npages
= buf
->size
>> 16;
59 buf
->page_size
= SZ_64K
;
61 npages
= buf
->size
>> PAGE_SHIFT
;
62 buf
->page_size
= PAGE_SIZE
;
65 buf
->sgt
= kzalloc(sizeof(struct sg_table
), GFP_KERNEL
);
67 DRM_ERROR("failed to allocate sg table.\n");
71 ret
= sg_alloc_table(buf
->sgt
, npages
, GFP_KERNEL
);
73 DRM_ERROR("failed to initialize sg table.\n");
79 buf
->kvaddr
= dma_alloc_writecombine(dev
->dev
, buf
->size
,
80 &buf
->dma_addr
, GFP_KERNEL
);
82 DRM_ERROR("failed to allocate buffer.\n");
87 buf
->pages
= kzalloc(sizeof(struct page
) * npages
, GFP_KERNEL
);
89 DRM_ERROR("failed to allocate pages.\n");
95 start_addr
= buf
->dma_addr
;
98 buf
->pages
[i
] = phys_to_page(start_addr
);
99 sg_set_page(sgl
, buf
->pages
[i
], buf
->page_size
, 0);
100 sg_dma_address(sgl
) = start_addr
;
101 start_addr
+= buf
->page_size
;
106 DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n",
107 (unsigned long)buf
->kvaddr
,
108 (unsigned long)buf
->dma_addr
,
113 dma_free_writecombine(dev
->dev
, buf
->size
, buf
->kvaddr
,
114 (dma_addr_t
)buf
->dma_addr
);
115 buf
->dma_addr
= (dma_addr_t
)NULL
;
117 sg_free_table(buf
->sgt
);
124 static void lowlevel_buffer_deallocate(struct drm_device
*dev
,
125 unsigned int flags
, struct exynos_drm_gem_buf
*buf
)
127 DRM_DEBUG_KMS("%s.\n", __FILE__
);
130 * release only physically continuous memory and
131 * non-continuous memory would be released by exynos
134 if (IS_NONCONTIG_BUFFER(flags
)) {
135 DRM_DEBUG_KMS("not support allocation type.\n");
139 if (!buf
->dma_addr
) {
140 DRM_DEBUG_KMS("dma_addr is invalid.\n");
144 DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n",
145 (unsigned long)buf
->kvaddr
,
146 (unsigned long)buf
->dma_addr
,
149 sg_free_table(buf
->sgt
);
157 dma_free_writecombine(dev
->dev
, buf
->size
, buf
->kvaddr
,
158 (dma_addr_t
)buf
->dma_addr
);
159 buf
->dma_addr
= (dma_addr_t
)NULL
;
162 struct exynos_drm_gem_buf
*exynos_drm_init_buf(struct drm_device
*dev
,
165 struct exynos_drm_gem_buf
*buffer
;
167 DRM_DEBUG_KMS("%s.\n", __FILE__
);
168 DRM_DEBUG_KMS("desired size = 0x%x\n", size
);
170 buffer
= kzalloc(sizeof(*buffer
), GFP_KERNEL
);
172 DRM_ERROR("failed to allocate exynos_drm_gem_buf.\n");
180 void exynos_drm_fini_buf(struct drm_device
*dev
,
181 struct exynos_drm_gem_buf
*buffer
)
183 DRM_DEBUG_KMS("%s.\n", __FILE__
);
186 DRM_DEBUG_KMS("buffer is null.\n");
194 int exynos_drm_alloc_buf(struct drm_device
*dev
,
195 struct exynos_drm_gem_buf
*buf
, unsigned int flags
)
199 * allocate memory region and set the memory information
200 * to vaddr and dma_addr of a buffer object.
202 if (lowlevel_buffer_allocate(dev
, flags
, buf
) < 0)
208 void exynos_drm_free_buf(struct drm_device
*dev
,
209 unsigned int flags
, struct exynos_drm_gem_buf
*buffer
)
212 lowlevel_buffer_deallocate(dev
, flags
, buffer
);