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