1 /*
2 * Copyright (C) 2021–2022 Beijing OSWare Technology Co., Ltd
3 * This file contains confidential and proprietary information of
4 * OSWare Technology 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 #include "drm_allocator.h"
19 #include <cinttypes>
20 #include <cerrno>
21 #include <fcntl.h>
22 #include <securec.h>
23 #include <xf86drm.h>
24 #include <sys/stat.h>
25 #include <xf86drmMode.h>
26 #include "display_common.h"
27 #include "drm_fourcc.h"
28 #include "hisilicon_drm.h"
29 namespace OHOS {
30 namespace HDI {
31 namespace DISPLAY {
32 const int pmode = 777;
Init()33 int32_t DrmAllocator::Init()
34 {
35 DISPLAY_LOGD();
36 int32_t ret;
37
38 ret = chmod(FILE_PATH, pmode);
39 if (ret == 0) {
40 DISPLAY_LOGD("drm file:%{public}s chmod success", FILE_PATH);
41 } else {
42 DISPLAY_LOGD("drm file:%{public}s chmod failed", FILE_PATH);
43 }
44
45 drmFd_ = open(FILE_PATH, O_RDWR);
46 DISPLAY_CHK_RETURN((drmFd_ < 0), DISPLAY_FAILURE,
47 DISPLAY_LOGE("can not open drm file : %{public}s errno: %{public}d ", FILE_PATH, errno));
48 ret = drmDropMaster(drmFd_);
49 if (ret != 0) {
50 DISPLAY_LOGW("can not drop master");
51 }
52 return DISPLAY_SUCCESS;
53 }
54
Allocate(const BufferInfo & bufferInfo,BufferHandle & handle)55 int32_t DrmAllocator::Allocate(const BufferInfo &bufferInfo, BufferHandle &handle)
56 {
57 int32_t ret;
58 int32_t fd;
59 struct drm_mode_create_dumb dumb = {0};
60 // create_dumb
61 dumb.width = bufferInfo.widthStride_;
62 dumb.height = bufferInfo.heightStride_;
63 dumb.flags = 0;
64 dumb.bpp = bufferInfo.bitsPerPixel_;
65 DISPLAY_LOGD();
66 ret = drmIoctl(drmFd_, DRM_IOCTL_MODE_CREATE_DUMB, &dumb);
67 DISPLAY_LOGI("fmt 0x%{public}x create dumb width: %{public}d height: %{public}d bpp: %{public}u pitch %{public}d "
68 "size %{public}llu",
69 handle.format, dumb.width, dumb.height, dumb.bpp, dumb.pitch, dumb.size);
70 DISPLAY_CHK_RETURN(
71 (ret != 0), DISPLAY_FAILURE, DISPLAY_LOGE("DRM_IOCTL_MODE_CREATE_DUMB failed errno %{public}d", errno));
72
73 ret = drmPrimeHandleToFD(drmFd_, dumb.handle, DRM_CLOEXEC | DRM_RDWR, &fd);
74 DISPLAY_CHK_RETURN(
75 (ret != 0), DISPLAY_FAILURE, DISPLAY_LOGE("can not get fd from prime handle errno: %{public}d", errno));
76 handle.fd = fd;
77 handle.size = dumb.size;
78 handle.phyAddr = GetPhysicalAddr(handle.fd);
79
80 if ((handle.usage & HBM_USE_MEM_FB) != 0) {
81 handle.format = PIXEL_FMT_BGRA_8888;
82 DISPLAY_LOGI("drm Allocate set to PIXEL_FMT_BGRA_8888 for FB");
83 }
84
85 struct drm_mode_destroy_dumb destoryDumb = {0};
86 destoryDumb.handle = dumb.handle;
87 ret = drmIoctl(drmFd_, DRM_IOCTL_MODE_DESTROY_DUMB, &destoryDumb);
88 if (ret != 0) {
89 DISPLAY_LOGW("can not destroy dumb errno: %{public}d", errno);
90 }
91
92 return DISPLAY_SUCCESS;
93 }
94
GetPhysicalAddr(int primeFd)95 uint64_t DrmAllocator::GetPhysicalAddr(int primeFd)
96 {
97 struct DrmHisiliconPhyaddr args;
98 int ret;
99 DISPLAY_LOGD();
100 (void)memset_s(&args, sizeof(args), 0, sizeof(args));
101 args.fd = primeFd;
102 ret = ioctl(drmFd_, DRM_IOCTL_HISILICON_GEM_FD_TO_PHYADDR, &args);
103 if (ret != 0) {
104 DISPLAY_LOGE("DRM_IOCTL_HISILICON_GEM_FD_TO_PHYADDR return failed");
105 }
106 DISPLAY_LOGD("phyaddr %{public}" PRIx64 "", args.phyaddr);
107 return args.phyaddr;
108 }
109
~DrmAllocator()110 DrmAllocator::~DrmAllocator()
111 {
112 DISPLAY_LOGD();
113 if (drmFd_ >= 0) {
114 close(drmFd_);
115 drmFd_ = -1;
116 }
117 }
118 } // namespace DISPLAY
119 } // namespace HDI
120 } // namespace OHOS