1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "ExynosDeviceInterface.h"
18
19 #include <cutils/properties.h>
20
21 #include <unordered_map>
22 #include <unordered_set>
23
24 #include "ExynosDevice.h"
25 #include "ExynosHWCDebug.h"
26 #include "ExynosMPP.h"
27 #include "ExynosResourceManager.h"
28 #include "ExynosResourceRestriction.h"
29
30 using namespace SOC_VERSION;
31
printDppRestriction(struct hwc_dpp_ch_restriction res)32 void ExynosDeviceInterface::printDppRestriction(struct hwc_dpp_ch_restriction res)
33 {
34 ALOGD("=========================================================");
35 ALOGD("id: %d", res.id);
36 ALOGD("hwc_dpp_restriction");
37 ALOGD("src_f_w (%d, %d, %d)", res.restriction.src_f_w.min, res.restriction.src_f_w.max, res.restriction.src_f_w.align);
38 ALOGD("src_f_h (%d, %d, %d)", res.restriction.src_f_h.min, res.restriction.src_f_h.max, res.restriction.src_f_h.align);
39 ALOGD("src_w (%d, %d, %d)", res.restriction.src_w.min, res.restriction.src_w.max, res.restriction.src_w.align);
40 ALOGD("src_h (%d, %d, %d)", res.restriction.src_h.min, res.restriction.src_h.max, res.restriction.src_h.align);
41 ALOGD("src_x_align(%d), src_y_align(%d)", res.restriction.src_x_align, res.restriction.src_y_align);
42
43 ALOGD("dst_f_w (%d, %d, %d)", res.restriction.dst_f_w.min, res.restriction.dst_f_w.max, res.restriction.dst_f_w.align);
44 ALOGD("dst_f_h (%d, %d, %d)", res.restriction.dst_f_h.min, res.restriction.dst_f_h.max, res.restriction.dst_f_h.align);
45 ALOGD("dst_w (%d, %d, %d)", res.restriction.dst_w.min, res.restriction.dst_w.max, res.restriction.dst_w.align);
46 ALOGD("dst_h (%d, %d, %d)", res.restriction.dst_h.min, res.restriction.dst_h.max, res.restriction.dst_h.align);
47 ALOGD("dst_x_align(%d), dst_y_align(%d)", res.restriction.dst_x_align, res.restriction.dst_y_align);
48 ALOGD("src_h_rot_max(%d)", res.restriction.src_h_rot_max);
49
50 ALOGD("blk_w (%d, %d, %d)", res.restriction.blk_w.min, res.restriction.blk_w.max, res.restriction.blk_w.align);
51 ALOGD("blk_h (%d, %d, %d)", res.restriction.blk_h.min, res.restriction.blk_h.max, res.restriction.blk_h.align);
52 ALOGD("blk_x_align(%d), blk_y_align(%d)", res.restriction.blk_x_align, res.restriction.blk_y_align);
53
54 ALOGD("format cnt: %zu", res.restriction.formats.size());
55 for(int i = 0; i < res.restriction.formats.size(); i++) {
56 ALOGD("[%d] format: %d", i, res.restriction.formats[i]);
57 }
58
59 ALOGD("scale down: %d, up: %d", res.restriction.scale_down, res.restriction.scale_up);
60 ALOGD("attr: 0x%lx", res.attr);
61 }
62
makeDPURestrictions()63 int32_t ExynosDeviceInterface::makeDPURestrictions() {
64 #ifdef DISABLE_READ_RESTRICTIONS
65 return -EINVAL;
66 #endif
67 int32_t ret = 0;
68
69 struct hwc_dpp_restrictions_info *dpuInfo = &mDPUInfo.dpuInfo;
70 HDEBUGLOGD(eDebugAttrSetting, "DPP ver : %d, cnt : %zu", dpuInfo->ver, dpuInfo->dpp_chs.size());
71 ExynosResourceManager *resourceManager = mExynosDevice->mResourceManager;
72
73 /* format resctriction */
74 for (int i = 0; i < dpuInfo->dpp_chs.size(); i++){
75 hwc_dpp_restriction r = dpuInfo->dpp_chs[i].restriction;
76 HDEBUGLOGD(eDebugAttrSetting, "id : %d, format count : %zu", i, r.formats.size());
77 }
78
79 /* Check attribute overlap */
80 std::unordered_set<unsigned long> attrs;
81 for (size_t i = 0; i < dpuInfo->dpp_chs.size(); ++i) {
82 const hwc_dpp_ch_restriction &r = dpuInfo->dpp_chs[i];
83 if (attrs.find(r.attr) != attrs.end())
84 mDPUInfo.overlap[i] = true;
85 else
86 attrs.insert(r.attr);
87 HDEBUGLOGD(eDebugAttrSetting, "Index : %zu, overlap %d", i, mDPUInfo.overlap[i]);
88 }
89
90 for (int i = 0; i < dpuInfo->dpp_chs.size(); i++){
91 if (mDPUInfo.overlap[i]) continue;
92 hwc_dpp_restriction r = dpuInfo->dpp_chs[i].restriction;
93 mpp_phycal_type_t hwType = resourceManager->getPhysicalType(i);
94 for (auto &format: r.formats) {
95 restriction_key_t queried_format;
96 queried_format.hwType = hwType;
97 queried_format.nodeType = NODE_NONE;
98 /* format is HAL format */
99 queried_format.format = format;
100 queried_format.reserved = 0;
101 resourceManager->makeFormatRestrictions(queried_format);
102 HDEBUGLOGD(eDebugAttrSetting, "%s : %d", getMPPStr(hwType).c_str(), format);
103 }
104 }
105
106 for (int i = 0; i < dpuInfo->dpp_chs.size(); i++){
107 if (mDPUInfo.overlap[i]) continue;
108 const hwc_dpp_restriction &r = dpuInfo->dpp_chs[i].restriction;
109
110 /* RGB size restrictions */
111 restriction_size rSize;
112 rSize.maxDownScale = r.scale_down;
113 rSize.maxUpScale = r.scale_up;
114 rSize.maxFullWidth = r.dst_f_w.max;
115 rSize.maxFullHeight = r.dst_f_h.max;
116 rSize.minFullWidth = r.dst_f_w.min;
117 rSize.minFullHeight = r.dst_f_h.min;;
118 rSize.fullWidthAlign = r.dst_x_align;
119 rSize.fullHeightAlign = r.dst_y_align;;
120 rSize.maxCropWidth = r.src_w.max;
121 rSize.maxCropHeight = r.src_h.max;
122 rSize.minCropWidth = r.src_w.min;
123 rSize.minCropHeight = r.src_h.min;
124 rSize.cropXAlign = r.src_x_align;
125 rSize.cropYAlign = r.src_y_align;
126 rSize.cropWidthAlign = r.blk_x_align;
127 rSize.cropHeightAlign = r.blk_y_align;
128
129 mpp_phycal_type_t hwType = resourceManager->getPhysicalType(i);
130 if (hwType <= MPP_DPP_NUM) {
131 auto newMaxDownscale =
132 static_cast<unsigned int>(property_get_int32("vendor.hwc.dpp.downscale", 0));
133 if (newMaxDownscale != 0) {
134 rSize.maxDownScale = min(rSize.maxDownScale, newMaxDownscale);
135 ALOGI("%s:: Apply DPP downscale restriction on 1/%d", __func__, rSize.maxDownScale);
136 }
137 }
138 resourceManager->makeSizeRestrictions(hwType, rSize, RESTRICTION_RGB);
139
140 /* YUV size restrictions */
141 rSize.minCropWidth = 32; //r.src_w.min;
142 rSize.minCropHeight = 32; //r.src_h.min;
143 rSize.fullWidthAlign = max(r.dst_x_align, YUV_CHROMA_H_SUBSAMPLE);
144 rSize.fullHeightAlign = max(r.dst_y_align, YUV_CHROMA_V_SUBSAMPLE);
145 rSize.cropXAlign = max(r.src_x_align, YUV_CHROMA_H_SUBSAMPLE);
146 rSize.cropYAlign = max(r.src_y_align, YUV_CHROMA_V_SUBSAMPLE);
147 rSize.cropWidthAlign = max(r.blk_x_align, YUV_CHROMA_H_SUBSAMPLE);
148 rSize.cropHeightAlign = max(r.blk_y_align, YUV_CHROMA_V_SUBSAMPLE);
149
150 resourceManager->makeSizeRestrictions(hwType, rSize, RESTRICTION_YUV);
151 }
152
153 for (auto it: resourceManager->getOtfMPPs()) {
154 if (mDPUInfo.dpuInfo.ppc)
155 it->setPPC(static_cast<float>(mDPUInfo.dpuInfo.ppc));
156 if (mDPUInfo.dpuInfo.max_disp_freq)
157 it->setClockKhz(mDPUInfo.dpuInfo.max_disp_freq);
158 }
159
160 return ret;
161 }
162
updateFeatureTable()163 int32_t ExynosDeviceInterface::updateFeatureTable() {
164 const struct hwc_dpp_restrictions_info &dpuInfo = mDPUInfo.dpuInfo;
165 if (mExynosDevice->mResourceManager == NULL)
166 return -1;
167
168 const ExynosResourceManager &resourceManager = *(mExynosDevice->mResourceManager);
169 const uint32_t featureTableCnt = resourceManager.getFeatureTableSize();
170
171 const int attrMapCnt = sizeof(dpu_attr_map_table)/sizeof(dpu_attr_map_t);
172 const int dpp_cnt = dpuInfo.dpp_chs.size();
173
174 HDEBUGLOGD(eDebugAttrSetting, "Before");
175 for (uint32_t j = 0; j < featureTableCnt; j++){
176 HDEBUGLOGD(eDebugAttrSetting, "type : %d, feature : 0x%lx",
177 feature_table[j].hwType,
178 (unsigned long)feature_table[j].attr);
179 }
180
181 // dpp count
182 for (int i = 0; i < dpp_cnt; i++){
183 hwc_dpp_ch_restriction c_r = dpuInfo.dpp_chs[i];
184 if (mDPUInfo.overlap[i]) continue;
185 HDEBUGLOGD(eDebugAttrSetting, "DPU attr : (ch:%d), 0x%lx", i, (unsigned long)c_r.attr);
186 mpp_phycal_type_t hwType = resourceManager.getPhysicalType(i);
187 // feature table count
188 for (uint32_t j = 0; j < featureTableCnt; j++){
189 if (feature_table[j].hwType == hwType) {
190 uint64_t attr = 0;
191 // dpp attr count
192 for (int k = 0; k < attrMapCnt; k++) {
193 if (c_r.attr & (1 << dpu_attr_map_table[k].dpp_attr)) {
194 attr |= dpu_attr_map_table[k].hwc_attr;
195 }
196 }
197 auto it = sw_feature_table.find(hwType);
198 if (it != sw_feature_table.end())
199 attr |= it->second;
200 feature_table[j].attr = attr;
201 }
202 }
203 }
204
205 HDEBUGLOGD(eDebugAttrSetting, "After");
206 for (uint32_t j = 0; j < featureTableCnt; j++){
207 HDEBUGLOGD(eDebugAttrSetting, "type : %d, feature : 0x%lx",
208 feature_table[j].hwType,
209 (unsigned long)feature_table[j].attr);
210 mExynosDevice->mResourceManager->mMPPAttrs.insert(std::make_pair((uint32_t)feature_table[j].hwType,
211 (uint64_t)feature_table[j].attr));
212 }
213 return 0;
214 }
215
216