xref: /OK3568_Linux_fs/external/camera_engine_rkaiq/rkaiq/xcore/dma_buffer.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * dma_buffer.cpp - DMA Buffer Implementation
3  *
4  *  Copyright (c) 2021 Rockchip Electronics Co., Ltd
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * Author: Cody Xie <cody.xie@rock-chips.com>
19  */
20 #include "dma_buffer.h"
21 
22 #include <fcntl.h>
23 #include <linux/dma-buf.h>
24 #include <sys/ioctl.h>
25 #include <sys/mman.h>
26 
27 #include <cassert>
28 
29 #include "xcam_log.h"
30 #include "xcam_std.h"
31 
32 namespace XCam {
33 
DmaBuffer(int fd,size_t size)34 DmaBuffer::DmaBuffer(int fd, size_t size) : fd_(fd), size_(size), ptr_(nullptr) {}
35 
~DmaBuffer()36 DmaBuffer::~DmaBuffer() {
37     if (ptr_ != nullptr) {
38         unmap();
39     }
40 }
41 
sync(int fd,DmaBufferDirection direction,bool start)42 XCamReturn DmaBuffer::sync(int fd, DmaBufferDirection direction, bool start) {
43     int ret;
44     struct dma_buf_sync sync = {0};
45 
46     XCAM_ASSERT(fd >= 0);
47 
48     if (direction == DmaBufferDirection::kDeviceToCPU) {
49         sync.flags = DMA_BUF_SYNC_READ;
50     } else if (direction == DmaBufferDirection::kCPUToDevice) {
51         sync.flags = DMA_BUF_SYNC_WRITE;
52     } else {
53         sync.flags = DMA_BUF_SYNC_RW;
54     }
55 
56     if (start) {
57         sync.flags |= DMA_BUF_SYNC_START;
58     } else {
59         sync.flags |= DMA_BUF_SYNC_END;
60     }
61 
62     ret = ioctl(fd, DMA_BUF_IOCTL_SYNC, &sync);
63     if (ret) {
64         LOGE("DMA_BUF_IOCTL_SYNC ioctl failed %s", strerror(errno));
65         return XCAM_RETURN_ERROR_IOCTL;
66     }
67 
68     LOGI("%s CPU access dir %d for BO fd %d", start ? "start" : "end", direction, fd);
69     return XCAM_RETURN_NO_ERROR;
70 }
71 
beginCpuAccess(DmaBufferDirection direction)72 XCamReturn DmaBuffer::beginCpuAccess(DmaBufferDirection direction) {
73     XCAM_ASSERT(ptr_ != nullptr);
74     return sync(fd_.Get(), direction, true);
75 }
76 
endCpuAccess(DmaBufferDirection direction)77 XCamReturn DmaBuffer::endCpuAccess(DmaBufferDirection direction) {
78     XCAM_ASSERT(ptr_ != nullptr);
79     return sync(fd_.Get(), direction, false);
80 }
81 
map()82 void* DmaBuffer::map() {
83     int ret;
84 
85     assert(((void)"could not map invalid dma_buf", fd_.Get() > 0 && ptr_ == nullptr && size_ > 0));
86 
87     ptr_ = mmap(0, size_, PROT_READ | PROT_WRITE, MAP_SHARED, fd_.Get(), 0);
88     if (ptr_ == MAP_FAILED) {
89         LOGE("dma_buf map failed %s", strerror(errno));
90         return nullptr;
91     }
92 
93     return ptr_;
94 }
95 
unmap()96 void DmaBuffer::unmap() {
97     assert(((void)"unmap dma_buf in wrong state", fd_.Get() > 0 && ptr_ != nullptr));
98 
99     munmap(ptr_, size_);
100     ptr_ = nullptr;
101 }
102 
getFd()103 int DmaBuffer::getFd() { return fd_.Get(); }
104 
getSize()105 size_t DmaBuffer::getSize() { return size_; }
106 
release()107 int DmaBuffer::release() { return fd_.Release(); }
108 
mapped()109 bool DmaBuffer::mapped() { return ptr_ == nullptr ? false : true; }
110 
111 }  // namespace XCam
112