blob: 03fb3b858de4a025770a9ea31560977be024ad27 [file] [log] [blame]
leng.fang91856072024-06-07 14:12:54 +08001/*
2 * Copyright (c) 2022 Amlogic, Inc. All rights reserved.
3 *
4 * This source code is subject to the terms and conditions defined in the
5 * file 'LICENSE' which is part of this source code package.
6 *
7 * Description:
8 */
9
10#include <sys/utsname.h>
11
12#include "DisplayAdapter.h"
13
14static int g_activeLevel= 3;
15
16bool update_sys_node_by_file(DisplayAttributeInfo& info, const string& in, string& out, UpdateType type) {
17 bool ret = false;
18 char buffer[MAX_BUF_LEN] = {0};
19 int len;
20 const char* node = info.sysfs_node;
21 bool is_read_only = info.is_read_only;
22 bool is_write_only = info.is_write_only;
23
24 switch (type) {
25 case UT_SET_VALUE:
26 if (is_read_only)
27 break;
28 info.new_value = in;
29 if (0 == sysfs_set_string(node, in.c_str())) {
30 info.current_value = in;
31 ret = true;
32 }
33 break;
34 case UT_GET_VALUE:
35 if (is_write_only)
36 break;
37 if (0 == sysfs_get_string(node, buffer, MAX_BUF_LEN)) {
38 out = buffer;
39 info.current_value = buffer;
40 ret = true;
41 }
42 break;
43 default:
44 break;
45 }
46 return ret;
47}
48
49bool update_sys_node_by_property(DisplayAttributeInfo& info, const string& in, string& out, UpdateType type) {
50 bool ret = false;
51 char buffer[MAX_BUF_LEN] = {0};
52 const char* node = info.sysfs_node;
53 bool is_read_only = info.is_read_only;
54 bool is_write_only = info.is_write_only;
55
56 switch (type) {
57 case UT_SET_VALUE:
58 if (is_read_only)
59 break;
60 info.new_value = in;
61 if (info.callBack && info.callBack->set_property) {
62 info.callBack->set_property(info.obj_id, node, atoi(in.c_str()));
63 info.current_value = in;
64 ret = true;
65 }
66 break;
67 case UT_GET_VALUE:
68 if (is_write_only)
69 break;
70 if (info.callBack && info.callBack->get_property) {
71 if (info.callBack->get_property(info.obj_id, node, buffer) == 0) {
72 out = buffer;
73 info.current_value = buffer;
74 ret = true;
75 }
76 }
77 break;
78 default:
79 break;
80 }
81 return ret;
82}
83
84DisplayAdapter::DisplayAdapter(drmModeCrtcPtr crtc, drmModeConnector *conn) {
85 initDisplayAttributeInfo(crtc, conn);
86}
87
88void DisplayAdapter::initDisplayAttributeInfo(drmModeCrtcPtr crtc, drmModeConnector *conn) {
89 struct utsname buf;
90 int major = 0;
91 int minor = 0;
92 if (0 == uname(&buf)) {
93 if (sscanf(buf.release, "%d.%d", &major, &minor) != 2) {
94 major = 0;
95 }
96 }
97 if (major == 0) {
98 MESON_LOGV("Can't determine kernel version for access sysfs!");
99 }
100
101#define DA_DEFINE(ID, INIT_VAL, UPDATE_FUN) \
102 display_attrs[DA_##ID] = { .name = DISPLAY_##ID, .attr_id = DA_##ID, .current_value = INIT_VAL, .new_value = INIT_VAL, .status_flags = 0, .update_fun = UPDATE_FUN, .sysfs_node = NULL, .obj_id = 0, .is_read_only = false, .is_write_only = false, .callBack = &mCallBack }
103
104 DA_DEFINE(AMDV_CAP, "0", update_sys_node_by_property);
105 DA_DEFINE(AMDV_CAP2, "0", update_sys_node_by_file);
106 DA_DEFINE(AMDV_ENABLE, "0", update_sys_node_by_property);
107 DA_DEFINE(AMDV_MODE, "0", update_sys_node_by_property);
108 DA_DEFINE(AMDV_STATUS, "0", update_sys_node_by_file);
109 DA_DEFINE(AMDV_POLICY, "0", update_sys_node_by_file);
110 DA_DEFINE(AMDV_LL_POLICY, "0", update_sys_node_by_file);
111 DA_DEFINE(AMDV_HDR_10_POLICY, "0", update_sys_node_by_file);
112 DA_DEFINE(AMDV_GRAPHICS_PRIORITY, "0", update_sys_node_by_file);
113 DA_DEFINE(HDR_CAP, "0", update_sys_node_by_property);
114 DA_DEFINE(HDR_CAP2, "0", update_sys_node_by_file);
115 DA_DEFINE(HDR_POLICY, "0", update_sys_node_by_property);
116 DA_DEFINE(HDR_MODE, "0", update_sys_node_by_file);
117 DA_DEFINE(SDR_MODE, "0", update_sys_node_by_file);
118 DA_DEFINE(HDMI_COLOR_ATTR, "0", update_sys_node_by_file);
119 DA_DEFINE(HDMI_AVMUTE, "0", update_sys_node_by_property);
120 DA_DEFINE(HDR_PRIORITY, "0", update_sys_node_by_file);
121 DA_DEFINE(FORCE_HDR_MODE, "0", update_sys_node_by_file);
122 DA_DEFINE(EDID_ATTR, "0", update_sys_node_by_property);
123 DA_DEFINE(FRAC_RATE_POLICY, "0", update_sys_node_by_property);
limin.tiana9a091a2024-09-23 07:54:32 +0000124 DA_DEFINE(VRR_SUPPORTED, "0", update_sys_node_by_property);
125 DA_DEFINE(VRR_ENABLED, "0", update_sys_node_by_property);
126 DA_DEFINE(BRR_UPDATE, "0", update_sys_node_by_property);
leng.fang91856072024-06-07 14:12:54 +0800127
128#define DA_SET_NODE(ID, NODE) \
129 display_attrs[DA_##ID].sysfs_node = NODE
130 if (major >= 5) {
131 DA_SET_NODE(AMDV_STATUS ,"/sys/module/aml_media/parameters/dolby_vision_status");
132 DA_SET_NODE(AMDV_POLICY ,"/sys/module/aml_media/parameters/dolby_vision_policy");
133 DA_SET_NODE(AMDV_LL_POLICY ,"/sys/module/aml_media/parameters/dolby_vision_ll_policy");
134 DA_SET_NODE(AMDV_HDR_10_POLICY ,"/sys/module/aml_media/parameters/dolby_vision_hdr10_policy");
135 DA_SET_NODE(AMDV_GRAPHICS_PRIORITY ,"/sys/module/aml_media/parameters/dolby_vision_graphics_priority");
136 DA_SET_NODE(HDR_MODE ,"/sys/module/aml_media/parameters/hdr_mode");
137 DA_SET_NODE(SDR_MODE ,"/sys/module/aml_media/parameters/sdr_mode");
138 } else {
139 DA_SET_NODE(AMDV_STATUS ,"/sys/module/amdolby_vision/parameters/dolby_vision_status");
140 DA_SET_NODE(AMDV_POLICY ,"/sys/module/amdolby_vision/parameters/dolby_vision_policy");
141 DA_SET_NODE(AMDV_LL_POLICY ,"/sys/module/amdolby_vision/parameters/dolby_vision_ll_policy");
142 DA_SET_NODE(AMDV_HDR_10_POLICY ,"/sys/module/amdolby_vision/parameters/dolby_vision_hdr10_policy");
143 DA_SET_NODE(AMDV_GRAPHICS_PRIORITY ,"/sys/module/amdolby_vision/parameters/dolby_vision_graphics_priority");
144 DA_SET_NODE(HDR_MODE ,"/sys/module/am_vecm/parameters/hdr_mode");
145 DA_SET_NODE(SDR_MODE ,"/sys/module/am_vecm/parameters/sdr_mode");
146 }
147 DA_SET_NODE(AMDV_CAP, "dv_cap");
148 DA_SET_NODE(AMDV_CAP2, "/sys/class/amhdmitx/amhdmitx0/dv_cap2");
149 DA_SET_NODE(AMDV_MODE, "dv_mode");
150 DA_SET_NODE(HDR_CAP, "hdr_cap");
151 DA_SET_NODE(HDR_CAP2, "/sys/class/amhdmitx/amhdmitx0/hdr_cap2");
152 DA_SET_NODE(HDR_POLICY, "meson.crtc.hdr_policy");
153 DA_SET_NODE(AMDV_ENABLE, "dv_enable");
154 DA_SET_NODE(HDMI_COLOR_ATTR ,"/sys/class/amhdmitx/amhdmitx0/attr");
155 DA_SET_NODE(HDMI_AVMUTE ,"MESON_DRM_HDMITX_PROP_AVMUTE");
156 DA_SET_NODE(HDR_PRIORITY, "/sys/class/amhdmitx/amhdmitx0/hdr_priority_mode");
157 DA_SET_NODE(FORCE_HDR_MODE, "/sys/module/aml_media/parameters/force_output");
158 DA_SET_NODE(EDID_ATTR, "EDID");
159 DA_SET_NODE(FRAC_RATE_POLICY, "FRAC_RATE_POLICY");
limin.tiana9a091a2024-09-23 07:54:32 +0000160 DA_SET_NODE(VRR_SUPPORTED, "vrr_capable");
161 DA_SET_NODE(VRR_ENABLED, "VRR_ENABLED");
162 DA_SET_NODE(BRR_UPDATE, "brr_update");
leng.fang91856072024-06-07 14:12:54 +0800163
164#define DA_SET_READ_ONLY(ID) \
165 display_attrs[DA_##ID].is_read_only = true
166 DA_SET_READ_ONLY(AMDV_CAP);
167 DA_SET_READ_ONLY(AMDV_CAP2);
168 DA_SET_READ_ONLY(AMDV_STATUS);
169 DA_SET_READ_ONLY(HDR_CAP);
170 DA_SET_READ_ONLY(HDR_CAP2);
limin.tiana9a091a2024-09-23 07:54:32 +0000171 DA_SET_READ_ONLY(VRR_SUPPORTED);
leng.fang91856072024-06-07 14:12:54 +0800172#define DA_SET_WRITE_ONLY(ID) \
173 display_attrs[DA_##ID].is_write_only= true
174 // DA_SET_WRITE_ONLY(AMDV_MODE);
175
176#define DA_SET_OBJ_ID(ID, id) \
177 display_attrs[DA_##ID].obj_id = id
178 if (conn) {
179 DA_SET_OBJ_ID(AMDV_CAP, conn->connector_id);
180 DA_SET_OBJ_ID(AMDV_CAP2, conn->connector_id);
181 DA_SET_OBJ_ID(HDR_CAP, conn->connector_id);
182 DA_SET_OBJ_ID(HDMI_AVMUTE, conn->connector_id);
183 DA_SET_OBJ_ID(EDID_ATTR, conn->connector_id);
184 DA_SET_OBJ_ID(FRAC_RATE_POLICY, conn->connector_id);
185 DA_SET_OBJ_ID(HDMI_COLOR_ATTR, conn->connector_id);
limin.tiana9a091a2024-09-23 07:54:32 +0000186 DA_SET_OBJ_ID(VRR_SUPPORTED, conn->connector_id);
leng.fang91856072024-06-07 14:12:54 +0800187 }
188 if (crtc) {
189 DA_SET_OBJ_ID(AMDV_MODE, crtc->crtc_id);
190 DA_SET_OBJ_ID(HDR_POLICY, crtc->crtc_id);
191 DA_SET_OBJ_ID(AMDV_ENABLE, crtc->crtc_id);
limin.tiana9a091a2024-09-23 07:54:32 +0000192 DA_SET_OBJ_ID(VRR_ENABLED, crtc->crtc_id);
193 DA_SET_OBJ_ID(BRR_UPDATE, crtc->crtc_id);
leng.fang91856072024-06-07 14:12:54 +0800194 }
195}
196
197bool DisplayAdapter::getDisplayMode(char *mode) {
198 if (mCallBack.get_mode)
199 return mCallBack.get_mode(mode);
200 return false;
201}
202
203bool DisplayAdapter::setDisplayMode(std::string &mode) {
204 char name[DRM_DISPLAY_MODE_LEN] = { 0 };
205
206 strncpy(name, mode.c_str(), DRM_DISPLAY_MODE_LEN - 1);
207 if (mCallBack.set_mode)
208 return mCallBack.set_mode(name);
209 return false;
210}
211
212bool DisplayAdapter::setDisplayRect(int x, int y, int width, int height) {
213 if (mCallBack.set_scaling_position)
214 mCallBack.set_scaling_position(x, y, width, height);
215 return true;
216}
217
218void DisplayAdapter::setColorAttribute(const char *attr) {
219 if (mCallBack.set_colorattribute)
220 mCallBack.set_colorattribute(attr);
221}
222
223DisplayAttributeInfo* DisplayAdapter::getDisplayAttributeInfo(const std::string &name)
224{
225 int i = 0;
226 for (i = 0; i < DA_DISPLAY_ATTRIBUTE__COUNT; i++) {
227 if (display_attrs[i].name == name) {
228 return &(display_attrs[i]);
229 }
230 }
231 return NULL;
232}
233
234int32_t DisplayAdapter::setColorAttrProperty(DisplayAttributeInfo *info, const std::string & hdmiColorAttr) {
235 uint32_t color_depth_value = 0;
236 uint32_t color_space_value = 0;
237 int ret = -1;
238
239 if (strstr(hdmiColorAttr.c_str(), "rgb")) {
240 color_space_value = 0;
241 } else if (strstr(hdmiColorAttr.c_str(), "422")) {
242 color_space_value = 1;
243 } else if (strstr(hdmiColorAttr.c_str(), "444")) {
244 color_space_value = 2;
245 } else if (strstr(hdmiColorAttr.c_str(), "420")) {
246 color_space_value = 3;
247 }
248
249 if (strstr(hdmiColorAttr.c_str(), "8bit")) {
250 color_depth_value = 8;
251 } else if (strstr(hdmiColorAttr.c_str(), "10bit")) {
252 color_depth_value = 10;
253 } else if (strstr(hdmiColorAttr.c_str(), "12bit")) {
254 color_depth_value = 12;
255 }
256
257 if (info->callBack && info->callBack->set_property) {
258 MESON_LOGD("set colorspace: %d, colordepth: %d", color_space_value, color_depth_value);
259 ret = info->callBack->set_property(info->obj_id, "color_space", color_space_value);
260 ret |= info->callBack->set_property(info->obj_id, "color_depth", color_depth_value);
261 }
262 return ret;
263}
264
265bool DisplayAdapter::setDisplayAttribute(const string& name, const string& value) {
266 DisplayAttributeInfo *info = getDisplayAttributeInfo(name);
267 if (!info)
268 return false;
269
270 if (!strcmp(info->name, DISPLAY_HDMI_COLOR_ATTR)) {
271 return setColorAttrProperty(info, value) == 0;
272 }
273
274 string out;
275 return info->update_fun(*info, value, out, UT_SET_VALUE);
276}
277
278bool DisplayAdapter::getColorAttrProperty(DisplayAttributeInfo *info, std::string& attribute) {
279 char buffer[MAX_BUF_LEN] = {0};
280 std::string colorSpace_str;
281
282 if (info->callBack && info->callBack->get_property) {
283 if (info->callBack->get_property(info->obj_id, "color_space", buffer) == 0) {
284 switch (atoi(buffer)) {
285 case 0:
286 colorSpace_str = "rgb";
287 break;
288 case 1:
289 colorSpace_str = "422";
290 break;
291 case 2:
292 colorSpace_str = "444";
293 break;
294 case 3:
295 colorSpace_str = "420";
296 break;
297 default:
298 MESON_LOGE(" invalid colorSpace:%s", buffer);
299 break;
300 }
301 } else {
302 colorSpace_str = "rgb";
303 }
304 memset(buffer, 0, MAX_BUF_LEN);
305 if (info->callBack->get_property(info->obj_id, "color_depth", buffer) < 0)
306 strcpy(buffer, "8");
307 attribute = colorSpace_str + "," + std::to_string(atoi(buffer)) + "bit";
308 MESON_LOGD(" colorSpace,colorDepth: %s", attribute.c_str());
309 return true;
310 }
311 return false;
312}
313
314bool DisplayAdapter::getDisplayAttribute(const string& name, string& value) {
315 DisplayAttributeInfo *info = getDisplayAttributeInfo(name);
316 bool ret = false;
317 string out = "";
318 if (!info)
319 return false;
320
321 if (!strcmp(info->name, DISPLAY_HDMI_COLOR_ATTR)) {
322 ret = getColorAttrProperty(info, value);
323 return ret;
324 }
325
326 ret = info->update_fun(*info, "", out, UT_GET_VALUE);
327 if (ret) {
328 value = out;
329 }
330 return ret;
331}
332
333void DisplayAdapter::registerCallBack(CompositorFunctionCallBack callback) {
334 mCallBack = callback;
335}
336
337void DisplayAdapter::setLogLevel(int level) {
338 g_activeLevel = level;
339}