blob: c061fe4b6e9d9cb95c4ed5aca85343e3ade7aca2 [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);
chen.wang10698b432024-11-12 13:08:14 +0000127 DA_DEFINE(HDMI_HDR_STATUS, "0", update_sys_node_by_property);
chen.wang188220682025-02-19 12:44:52 +0000128 DA_DEFINE(UPDATE, "0", update_sys_node_by_property);
leng.fang91856072024-06-07 14:12:54 +0800129
130#define DA_SET_NODE(ID, NODE) \
131 display_attrs[DA_##ID].sysfs_node = NODE
132 if (major >= 5) {
133 DA_SET_NODE(AMDV_STATUS ,"/sys/module/aml_media/parameters/dolby_vision_status");
134 DA_SET_NODE(AMDV_POLICY ,"/sys/module/aml_media/parameters/dolby_vision_policy");
135 DA_SET_NODE(AMDV_LL_POLICY ,"/sys/module/aml_media/parameters/dolby_vision_ll_policy");
136 DA_SET_NODE(AMDV_HDR_10_POLICY ,"/sys/module/aml_media/parameters/dolby_vision_hdr10_policy");
137 DA_SET_NODE(AMDV_GRAPHICS_PRIORITY ,"/sys/module/aml_media/parameters/dolby_vision_graphics_priority");
138 DA_SET_NODE(HDR_MODE ,"/sys/module/aml_media/parameters/hdr_mode");
139 DA_SET_NODE(SDR_MODE ,"/sys/module/aml_media/parameters/sdr_mode");
140 } else {
141 DA_SET_NODE(AMDV_STATUS ,"/sys/module/amdolby_vision/parameters/dolby_vision_status");
142 DA_SET_NODE(AMDV_POLICY ,"/sys/module/amdolby_vision/parameters/dolby_vision_policy");
143 DA_SET_NODE(AMDV_LL_POLICY ,"/sys/module/amdolby_vision/parameters/dolby_vision_ll_policy");
144 DA_SET_NODE(AMDV_HDR_10_POLICY ,"/sys/module/amdolby_vision/parameters/dolby_vision_hdr10_policy");
145 DA_SET_NODE(AMDV_GRAPHICS_PRIORITY ,"/sys/module/amdolby_vision/parameters/dolby_vision_graphics_priority");
146 DA_SET_NODE(HDR_MODE ,"/sys/module/am_vecm/parameters/hdr_mode");
147 DA_SET_NODE(SDR_MODE ,"/sys/module/am_vecm/parameters/sdr_mode");
148 }
149 DA_SET_NODE(AMDV_CAP, "dv_cap");
150 DA_SET_NODE(AMDV_CAP2, "/sys/class/amhdmitx/amhdmitx0/dv_cap2");
151 DA_SET_NODE(AMDV_MODE, "dv_mode");
152 DA_SET_NODE(HDR_CAP, "hdr_cap");
153 DA_SET_NODE(HDR_CAP2, "/sys/class/amhdmitx/amhdmitx0/hdr_cap2");
154 DA_SET_NODE(HDR_POLICY, "meson.crtc.hdr_policy");
155 DA_SET_NODE(AMDV_ENABLE, "dv_enable");
156 DA_SET_NODE(HDMI_COLOR_ATTR ,"/sys/class/amhdmitx/amhdmitx0/attr");
157 DA_SET_NODE(HDMI_AVMUTE ,"MESON_DRM_HDMITX_PROP_AVMUTE");
158 DA_SET_NODE(HDR_PRIORITY, "/sys/class/amhdmitx/amhdmitx0/hdr_priority_mode");
159 DA_SET_NODE(FORCE_HDR_MODE, "/sys/module/aml_media/parameters/force_output");
160 DA_SET_NODE(EDID_ATTR, "EDID");
161 DA_SET_NODE(FRAC_RATE_POLICY, "FRAC_RATE_POLICY");
limin.tiana9a091a2024-09-23 07:54:32 +0000162 DA_SET_NODE(VRR_SUPPORTED, "vrr_capable");
163 DA_SET_NODE(VRR_ENABLED, "VRR_ENABLED");
164 DA_SET_NODE(BRR_UPDATE, "brr_update");
chen.wang10698b432024-11-12 13:08:14 +0000165 DA_SET_NODE(HDMI_HDR_STATUS, "hdmi_hdr_status");
chen.wang188220682025-02-19 12:44:52 +0000166 DA_SET_NODE(UPDATE, "UPDATE");
leng.fang91856072024-06-07 14:12:54 +0800167
168#define DA_SET_READ_ONLY(ID) \
169 display_attrs[DA_##ID].is_read_only = true
170 DA_SET_READ_ONLY(AMDV_CAP);
171 DA_SET_READ_ONLY(AMDV_CAP2);
172 DA_SET_READ_ONLY(AMDV_STATUS);
173 DA_SET_READ_ONLY(HDR_CAP);
174 DA_SET_READ_ONLY(HDR_CAP2);
limin.tiana9a091a2024-09-23 07:54:32 +0000175 DA_SET_READ_ONLY(VRR_SUPPORTED);
chen.wang10698b432024-11-12 13:08:14 +0000176 DA_SET_READ_ONLY(HDMI_HDR_STATUS);
leng.fang91856072024-06-07 14:12:54 +0800177#define DA_SET_WRITE_ONLY(ID) \
178 display_attrs[DA_##ID].is_write_only= true
179 // DA_SET_WRITE_ONLY(AMDV_MODE);
180
181#define DA_SET_OBJ_ID(ID, id) \
182 display_attrs[DA_##ID].obj_id = id
183 if (conn) {
184 DA_SET_OBJ_ID(AMDV_CAP, conn->connector_id);
185 DA_SET_OBJ_ID(AMDV_CAP2, conn->connector_id);
186 DA_SET_OBJ_ID(HDR_CAP, conn->connector_id);
187 DA_SET_OBJ_ID(HDMI_AVMUTE, conn->connector_id);
188 DA_SET_OBJ_ID(EDID_ATTR, conn->connector_id);
189 DA_SET_OBJ_ID(FRAC_RATE_POLICY, conn->connector_id);
190 DA_SET_OBJ_ID(HDMI_COLOR_ATTR, conn->connector_id);
limin.tiana9a091a2024-09-23 07:54:32 +0000191 DA_SET_OBJ_ID(VRR_SUPPORTED, conn->connector_id);
chen.wang10698b432024-11-12 13:08:14 +0000192 DA_SET_OBJ_ID(HDMI_HDR_STATUS, conn->connector_id);
chen.wang188220682025-02-19 12:44:52 +0000193 DA_SET_OBJ_ID(UPDATE, conn->connector_id);
leng.fang91856072024-06-07 14:12:54 +0800194 }
195 if (crtc) {
196 DA_SET_OBJ_ID(AMDV_MODE, crtc->crtc_id);
197 DA_SET_OBJ_ID(HDR_POLICY, crtc->crtc_id);
198 DA_SET_OBJ_ID(AMDV_ENABLE, crtc->crtc_id);
limin.tiana9a091a2024-09-23 07:54:32 +0000199 DA_SET_OBJ_ID(VRR_ENABLED, crtc->crtc_id);
200 DA_SET_OBJ_ID(BRR_UPDATE, crtc->crtc_id);
leng.fang91856072024-06-07 14:12:54 +0800201 }
202}
203
204bool DisplayAdapter::getDisplayMode(char *mode) {
205 if (mCallBack.get_mode)
206 return mCallBack.get_mode(mode);
207 return false;
208}
209
210bool DisplayAdapter::setDisplayMode(std::string &mode) {
211 char name[DRM_DISPLAY_MODE_LEN] = { 0 };
212
213 strncpy(name, mode.c_str(), DRM_DISPLAY_MODE_LEN - 1);
214 if (mCallBack.set_mode)
215 return mCallBack.set_mode(name);
216 return false;
217}
218
219bool DisplayAdapter::setDisplayRect(int x, int y, int width, int height) {
220 if (mCallBack.set_scaling_position)
221 mCallBack.set_scaling_position(x, y, width, height);
222 return true;
223}
224
225void DisplayAdapter::setColorAttribute(const char *attr) {
226 if (mCallBack.set_colorattribute)
227 mCallBack.set_colorattribute(attr);
228}
229
230DisplayAttributeInfo* DisplayAdapter::getDisplayAttributeInfo(const std::string &name)
231{
232 int i = 0;
233 for (i = 0; i < DA_DISPLAY_ATTRIBUTE__COUNT; i++) {
234 if (display_attrs[i].name == name) {
235 return &(display_attrs[i]);
236 }
237 }
238 return NULL;
239}
240
241int32_t DisplayAdapter::setColorAttrProperty(DisplayAttributeInfo *info, const std::string & hdmiColorAttr) {
242 uint32_t color_depth_value = 0;
243 uint32_t color_space_value = 0;
244 int ret = -1;
245
246 if (strstr(hdmiColorAttr.c_str(), "rgb")) {
247 color_space_value = 0;
248 } else if (strstr(hdmiColorAttr.c_str(), "422")) {
249 color_space_value = 1;
250 } else if (strstr(hdmiColorAttr.c_str(), "444")) {
251 color_space_value = 2;
252 } else if (strstr(hdmiColorAttr.c_str(), "420")) {
253 color_space_value = 3;
254 }
255
256 if (strstr(hdmiColorAttr.c_str(), "8bit")) {
257 color_depth_value = 8;
258 } else if (strstr(hdmiColorAttr.c_str(), "10bit")) {
259 color_depth_value = 10;
260 } else if (strstr(hdmiColorAttr.c_str(), "12bit")) {
261 color_depth_value = 12;
262 }
263
264 if (info->callBack && info->callBack->set_property) {
265 MESON_LOGD("set colorspace: %d, colordepth: %d", color_space_value, color_depth_value);
266 ret = info->callBack->set_property(info->obj_id, "color_space", color_space_value);
267 ret |= info->callBack->set_property(info->obj_id, "color_depth", color_depth_value);
268 }
269 return ret;
270}
271
272bool DisplayAdapter::setDisplayAttribute(const string& name, const string& value) {
273 DisplayAttributeInfo *info = getDisplayAttributeInfo(name);
274 if (!info)
275 return false;
276
277 if (!strcmp(info->name, DISPLAY_HDMI_COLOR_ATTR)) {
278 return setColorAttrProperty(info, value) == 0;
279 }
280
281 string out;
282 return info->update_fun(*info, value, out, UT_SET_VALUE);
283}
284
285bool DisplayAdapter::getColorAttrProperty(DisplayAttributeInfo *info, std::string& attribute) {
286 char buffer[MAX_BUF_LEN] = {0};
287 std::string colorSpace_str;
288
289 if (info->callBack && info->callBack->get_property) {
290 if (info->callBack->get_property(info->obj_id, "color_space", buffer) == 0) {
291 switch (atoi(buffer)) {
292 case 0:
293 colorSpace_str = "rgb";
294 break;
295 case 1:
296 colorSpace_str = "422";
297 break;
298 case 2:
299 colorSpace_str = "444";
300 break;
301 case 3:
302 colorSpace_str = "420";
303 break;
304 default:
305 MESON_LOGE(" invalid colorSpace:%s", buffer);
306 break;
307 }
308 } else {
309 colorSpace_str = "rgb";
310 }
311 memset(buffer, 0, MAX_BUF_LEN);
312 if (info->callBack->get_property(info->obj_id, "color_depth", buffer) < 0)
313 strcpy(buffer, "8");
314 attribute = colorSpace_str + "," + std::to_string(atoi(buffer)) + "bit";
315 MESON_LOGD(" colorSpace,colorDepth: %s", attribute.c_str());
316 return true;
317 }
318 return false;
319}
320
321bool DisplayAdapter::getDisplayAttribute(const string& name, string& value) {
322 DisplayAttributeInfo *info = getDisplayAttributeInfo(name);
323 bool ret = false;
324 string out = "";
325 if (!info)
326 return false;
327
328 if (!strcmp(info->name, DISPLAY_HDMI_COLOR_ATTR)) {
329 ret = getColorAttrProperty(info, value);
330 return ret;
331 }
332
333 ret = info->update_fun(*info, "", out, UT_GET_VALUE);
334 if (ret) {
335 value = out;
336 }
337 return ret;
338}
339
340void DisplayAdapter::registerCallBack(CompositorFunctionCallBack callback) {
341 mCallBack = callback;
342}
343
344void DisplayAdapter::setLogLevel(int level) {
345 g_activeLevel = level;
346}