blob: 08b54a78397a78320dd0560dbd84dcae9890a2c0 [file] [log] [blame]
limin.tian20df7d42023-02-10 10:05:52 +08001/*
2 * Copyright (c) 2023 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#include <stdio.h>
10#include <stdlib.h>
11#include <fcntl.h>
12#include <unistd.h>
13#include <errno.h>
14#include <xf86drm.h>
15#include <xf86drmMode.h>
16#include <linux/string.h>
17#include "libdrm_meson_connector.h"
18#include "libdrm_meson_property.h"
19#include "meson_drm_settings.h"
20
limin.tian20df7d42023-02-10 10:05:52 +080021#define DEFAULT_CARD "/dev/dri/card0"
22#define PROP_NAME_MAX_LEN 50
23static int meson_drm_get_crtc_prop_value( int drmFd, MESON_CONNECTOR_TYPE connType,
24 char* name, uint32_t* prop_value );
25static int meson_drm_get_conn_prop_value( int drmFd, MESON_CONNECTOR_TYPE connType,
26 char* name, uint32_t* propValue );
27static int meson_drm_get_prop_value(int drmFd, MESON_CONNECTOR_TYPE connType,
28 uint32_t objType, char* name, uint32_t* propValue );
29
30static struct mesonConnector* get_current_connector(int drmFd, MESON_CONNECTOR_TYPE connType);
31static int meson_drm_set_property(int drmFd, drmModeAtomicReq *req, uint32_t objId,
32 uint32_t objType, char* name, uint64_t value);
33
34static int meson_drm_get_prop_value(int drmFd, MESON_CONNECTOR_TYPE connType, uint32_t objType, char* name, uint32_t* propValue )
35{
36 int ret = -1;
37 int objID = -1;
38 struct mesonConnector* conn = NULL;
39 if ( drmFd < 0 || name == NULL || propValue == NULL)
40 {
limin.tianfe2ab442023-03-06 08:40:15 +000041 fprintf(stderr, "\n%s %d drmfd invalid, or property name invalid\n",__FUNCTION__,__LINE__);
limin.tian20df7d42023-02-10 10:05:52 +080042 goto out;
43 }
44 conn = get_current_connector(drmFd, connType);
45 if ( conn == NULL )
46 {
limin.tianfe2ab442023-03-06 08:40:15 +000047 fprintf(stderr, "\n%s %d get_current_connector fail\n",__FUNCTION__,__LINE__);
limin.tian20df7d42023-02-10 10:05:52 +080048 goto out;
49 }
50 objID = mesonConnectorGetId(conn);
51 if (objType == DRM_MODE_OBJECT_CRTC)
52 objID = mesonConnectorGetCRTCId(conn);
53 struct mesonProperty* meson_prop = NULL;
54 meson_prop = mesonPropertyCreate(drmFd, objID, objType, name);
55 if (!meson_prop) {
56 printf("\n meson_prop create fail\n");
57 goto out;
58 }
59 uint64_t value = mesonPropertyGetValue(meson_prop);
60 *propValue = (uint32_t)value;
limin.tianfe2ab442023-03-06 08:40:15 +000061 fprintf(stderr, "\n prop value:%llu objID:%d,name:%s\n",value, objID,name);
limin.tian20df7d42023-02-10 10:05:52 +080062 mesonPropertyDestroy(meson_prop);
63 ret = 0;
64out:
65 if (conn)
66 mesonConnectorDestroy(drmFd,conn);
67 return ret;
68}
69
70static int meson_drm_get_conn_prop_value( int drmFd, MESON_CONNECTOR_TYPE conn_type, char* name, uint32_t* prop_value )
71{
72 return meson_drm_get_prop_value( drmFd, conn_type, DRM_MODE_OBJECT_CONNECTOR, name, prop_value );
73}
74
75static int meson_drm_get_crtc_prop_value( int drmFd, MESON_CONNECTOR_TYPE conn_type, char* name, uint32_t* prop_value )
76{
77 return meson_drm_get_prop_value( drmFd, conn_type, DRM_MODE_OBJECT_CRTC, name, prop_value );
78}
79
80static struct mesonConnector* get_current_connector(int drmFd, MESON_CONNECTOR_TYPE connType)
81{
82 struct mesonConnector* connector = NULL;
83 int drmConnType = DRM_MODE_CONNECTOR_HDMIA;
84 if (drmFd < 0) {
limin.tianfe2ab442023-03-06 08:40:15 +000085 fprintf(stderr, "\n %s %d invalid drmFd return\n",__FUNCTION__,__LINE__);
limin.tian20df7d42023-02-10 10:05:52 +080086 return NULL;
87 }
88 switch (connType)
89 {
90 case MESON_CONNECTOR_HDMIA:
91 drmConnType = DRM_MODE_CONNECTOR_HDMIA;
92 break;
93 case MESON_CONNECTOR_HDMIB:
94 drmConnType = DRM_MODE_CONNECTOR_HDMIB;
95 break;
96 case MESON_CONNECTOR_LVDS:
97 drmConnType = DRM_MODE_CONNECTOR_LVDS;
98 break;
99 case MESON_CONNECTOR_CVBS:
100 drmConnType = DRM_MODE_CONNECTOR_TV;
limin.tiandcd053f2023-04-24 08:27:18 +0000101 break;
limin.tian20df7d42023-02-10 10:05:52 +0800102 default :
103 drmConnType = DRM_MODE_CONNECTOR_HDMIA;
104 break;
105 }
106 connector = mesonConnectorCreate(drmFd, drmConnType);
107 return connector;
108}
109int meson_open_drm()
110{
111 int ret_fd = -1;
112 const char *card;
113 int ret = -1;
114 card= getenv("WESTEROS_DRM_CARD");
115 if ( !card ) {
116 card = DEFAULT_CARD;
117 }
118 ret_fd = open(card, O_RDONLY|O_CLOEXEC);
119 if ( ret_fd < 0 )
limin.tianfe2ab442023-03-06 08:40:15 +0000120 fprintf(stderr, "\n meson_open_drm drm card:%s open fail\n",card);
limin.tian20df7d42023-02-10 10:05:52 +0800121 else
122 drmDropMaster(ret_fd);
123 ret = drmSetClientCap(ret_fd, DRM_CLIENT_CAP_ATOMIC, 1);
124 if (ret < 0)
limin.tianfe2ab442023-03-06 08:40:15 +0000125 fprintf(stderr, "Unable to set DRM atomic capability\n");
126
limin.tian20df7d42023-02-10 10:05:52 +0800127 ret = drmSetClientCap(ret_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
128 if (ret < 0)
limin.tianfe2ab442023-03-06 08:40:15 +0000129 fprintf(stderr, "Unable to set UNIVERSAL_PLANES\n");
limin.tian20df7d42023-02-10 10:05:52 +0800130 return ret_fd;
131}
132void meson_close_drm(int drmFd)
133{
134 if (drmFd >= 0)
135 close(drmFd);
136}
chen.wang154f11d52023-04-14 07:56:49 +0000137
limin.tian20df7d42023-02-10 10:05:52 +0800138static int meson_drm_set_property(int drmFd, drmModeAtomicReq *req, uint32_t objId,
139 uint32_t objType, char* name, uint64_t value)
140{
141 uint32_t propId;
142 int rc = -1;
143 if (drmFd < 0 || req == NULL) {
limin.tianfe2ab442023-03-06 08:40:15 +0000144 fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
limin.tian20df7d42023-02-10 10:05:52 +0800145 return rc;
146 }
147 struct mesonProperty *prop = NULL;
148 prop = mesonPropertyCreate(drmFd, objId, objType, name);
149 propId = mesonPropertyGetId(prop);
150 mesonPropertyDestroy(prop);
limin.tiandcd053f2023-04-24 08:27:18 +0000151 fprintf(stderr, "\nmeson_drm_set_property name:%s objId:%d propId:%d value:%llu\n", name, objId, propId, value);
limin.tian20df7d42023-02-10 10:05:52 +0800152 rc = drmModeAtomicAddProperty( req, objId, propId, value );
153 if (rc < 0)
limin.tianfe2ab442023-03-06 08:40:15 +0000154 fprintf(stderr, "\n %s %d meson_drm_set_property fail\n",__FUNCTION__,__LINE__);
limin.tian20df7d42023-02-10 10:05:52 +0800155 return rc;
156}
157
chen.wang154f11d52023-04-14 07:56:49 +0000158int meson_drm_getPreferredMode( DisplayMode* mode) {
159 int ret = -1;
160 int i = 0;
161 int count = 0;
162 drmModeModeInfo* modes = NULL;
163 int drmFd = -1;
164 struct mesonConnector* conn = NULL;
165 drmFd = meson_open_drm();
166 conn = mesonConnectorCreate(drmFd, DRM_MODE_CONNECTOR_HDMIA);
167 if (conn == NULL || drmFd < 0)
168 {
169 printf("\n%s %d connector create fail\n",__FUNCTION__,__LINE__);
170 }
171 if (0 != mesonConnectorGetModes(conn, drmFd, &modes, &count))
172 goto out;
173 for (i = 0; i < count; i++)
174 {
175 if (modes[i].type & DRM_MODE_TYPE_PREFERRED)
176 {
177 mode->w = modes[i].hdisplay;
178 mode->h = modes[i].vdisplay;
179 mode->interlace = (modes[i].flags & DRM_MODE_FLAG_INTERLACE) ? true : false;
180 strcpy(mode->name, modes[i].name );
181 break;
182 }
183 }
184 ret = 0;
185out:
186 if (conn)
187 mesonConnectorDestroy(drmFd,conn);
188 if (drmFd >= 0 )
189 close(drmFd);
190 return ret;
191}
192
193int meson_drm_getsupportedModesList(int drmFd, DisplayMode** modeInfo, int* modeCount )
194{
195 int ret = -1;
196 struct mesonConnector* conn = NULL;
197 if ( drmFd < 0) {
198 fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
199 return ret;
200 }
201 conn = mesonConnectorCreate(drmFd, DRM_MODE_CONNECTOR_HDMIA);
202 if (conn == NULL || drmFd < 0)
203 {
204 printf("\n%s %d connector create fail\n",__FUNCTION__,__LINE__);
205 }
206 drmModeModeInfo* modeall = NULL;
207 int count = 0;
208 int i = 0;
209 if (0 != mesonConnectorGetModes(conn, drmFd, &modeall, &count))
210 goto out;
211 DisplayMode* modestemp = (DisplayMode*)calloc(count, sizeof(DisplayMode));
212 for (i = 0; i < count; i++)
213 {
214 modestemp[i].w = modeall[i].hdisplay;
215 modestemp[i].h = modeall[i].vdisplay;
216 modestemp[i].vrefresh = modeall[i].vrefresh;
217 modestemp[i].interlace = (modeall[i].flags & DRM_MODE_FLAG_INTERLACE) ? true : false;
218 strcpy(modestemp[i].name, modeall[i].name );
219 }
220 *modeCount = count;
221 *modeInfo = modestemp;
222 ret = 0;
223out:
224 if (conn)
225 mesonConnectorDestroy(drmFd,conn);
226 return ret;
227}
228
limin.tian20df7d42023-02-10 10:05:52 +0800229int meson_drm_getModeInfo(int drmFd, MESON_CONNECTOR_TYPE connType, DisplayMode* modeInfo)
230{
231 int ret = -1;
232 struct mesonConnector* conn = NULL;
233 drmModeModeInfo* mode = NULL;
234 if (modeInfo == NULL || drmFd < 0) {
limin.tianfe2ab442023-03-06 08:40:15 +0000235 fprintf(stderr, "\n %s %d modeInfo == NULL || drmFd < 0 return\n",__FUNCTION__,__LINE__);
limin.tian20df7d42023-02-10 10:05:52 +0800236 return ret;
237 }
238 conn = get_current_connector(drmFd, connType);
239 if ( conn ) {
240 mode = mesonConnectorGetCurMode(drmFd, conn);
241 if (mode) {
242 modeInfo->w = mode->hdisplay;
243 modeInfo->h = mode->vdisplay;
244 modeInfo->vrefresh = mode->vrefresh;
245 modeInfo->interlace = mode->flags & DRM_MODE_FLAG_INTERLACE;
246 strcpy(modeInfo->name, mode->name);
247 free(mode);
248 mode = NULL;
249 ret = 0;
250 } else {
limin.tianfe2ab442023-03-06 08:40:15 +0000251 fprintf(stderr, "\n %s %d mode get fail \n",__FUNCTION__,__LINE__);
limin.tian20df7d42023-02-10 10:05:52 +0800252 }
253 } else {
limin.tianfe2ab442023-03-06 08:40:15 +0000254 fprintf(stderr, "\n %s %d conn create fail \n",__FUNCTION__,__LINE__);
limin.tian20df7d42023-02-10 10:05:52 +0800255 }
256 if (conn)
257 mesonConnectorDestroy(drmFd,conn);
258 return ret;
259}
260int meson_drm_changeMode(int drmFd, drmModeAtomicReq *req, DisplayMode* modeInfo, MESON_CONNECTOR_TYPE connType)
261{
262 int ret = -1;
263 struct mesonConnector* conn = NULL;
264 drmModeModeInfo drm_mode;
265 int i;
266 bool interlace = false;
267 bool found = false;
268 int rc = -1;
269 int rc1 = -1;
270 int rc2 = -1;
271 int rc3 = -1;
272 uint32_t connId;
273 uint32_t crtcId;
274
275 uint32_t blobId = 0;
276 drmModeModeInfo* modes = NULL;
277 int modesNumber = 0;
278
279 if (modeInfo == NULL || drmFd < 0 || req == NULL) {
limin.tianfe2ab442023-03-06 08:40:15 +0000280 fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
limin.tian20df7d42023-02-10 10:05:52 +0800281 return ret;
282 }
limin.tiandcd053f2023-04-24 08:27:18 +0000283 if (connType == MESON_CONNECTOR_CVBS)
284 {
285 struct mesonConnector* connHDMI = NULL;
286 uint32_t HDMIconnId;
287 int rc4 = -1;
288 connHDMI = get_current_connector(drmFd, MESON_CONNECTOR_HDMIA);
289 HDMIconnId = mesonConnectorGetId(connHDMI);
290 rc4 = meson_drm_set_property(drmFd, req, HDMIconnId, DRM_MODE_OBJECT_CONNECTOR, "CRTC_ID", 0);
291 mesonConnectorDestroy(drmFd,connHDMI);
292 fprintf(stderr, "\n %s %d change mode to cvbs, disconnect HDMI :%d \n",__FUNCTION__,__LINE__,rc4);
293 }
limin.tian20df7d42023-02-10 10:05:52 +0800294 conn = get_current_connector(drmFd, connType);
295 connId = mesonConnectorGetId(conn);
296 crtcId = mesonConnectorGetCRTCId(conn);
297 if ( conn ) {
298 mesonConnectorGetModes(conn, drmFd, &modes, &modesNumber);
299 for ( i = 0; i < modesNumber; i++ ) {
300 interlace = (modes[i].flags & DRM_MODE_FLAG_INTERLACE);
301 if ( (modeInfo->w == modes[i].hdisplay)
302 && (modeInfo->h == modes[i].vdisplay)
303 && (modeInfo->vrefresh == modes[i].vrefresh)
304 && (interlace == modeInfo->interlace)
305 ) {
306 drm_mode = modes[i];
307 found = true;
308 break;
309 }
310 }
311 } else {
limin.tianfe2ab442023-03-06 08:40:15 +0000312 fprintf(stderr, "\n %s %d conn create fail \n",__FUNCTION__,__LINE__);
limin.tian20df7d42023-02-10 10:05:52 +0800313 }
314
315 if (found) {
316 rc1 = meson_drm_set_property(drmFd, req, connId, DRM_MODE_OBJECT_CONNECTOR, "CRTC_ID", crtcId);
317 rc = drmModeCreatePropertyBlob( drmFd, &drm_mode, sizeof(drm_mode), &blobId );
318 if (rc == 0) {
319 rc2 = meson_drm_set_property(drmFd, req, crtcId, DRM_MODE_OBJECT_CRTC, "MODE_ID", blobId);
320 rc3 = meson_drm_set_property(drmFd, req, crtcId, DRM_MODE_OBJECT_CRTC, "ACTIVE", 1);
limin.tianfe2ab442023-03-06 08:40:15 +0000321 fprintf(stderr, "\n %s %d rc1:%d rc:%d rc2:%d, rc3:%d\n",__FUNCTION__,__LINE__, rc1, rc,rc2,rc3);
limin.tian20df7d42023-02-10 10:05:52 +0800322 if (rc1 >= 0 && rc2 >= 0 && rc3 >= 0)
323 ret = 0;
324 }
325 }
326 if (conn)
327 mesonConnectorDestroy(drmFd,conn);
328 return ret;
329}
330
331ENUM_MESON_CONN_CONNECTION meson_drm_getConnectionStatus(int drmFd, MESON_CONNECTOR_TYPE connType)
332{
333 ENUM_MESON_CONN_CONNECTION ret = MESON_UNKNOWNCONNECTION;
334 struct mesonConnector* conn = NULL;
335 if ( drmFd < 0) {
limin.tianfe2ab442023-03-06 08:40:15 +0000336 fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
limin.tian20df7d42023-02-10 10:05:52 +0800337 return ret;
338 }
339 conn = get_current_connector(drmFd, connType);
340 if (conn) {
341 int ConnectState = -1;
342 ConnectState = mesonConnectorGetConnectState(conn);
343 if (ConnectState == 1) {
344 ret = MESON_CONNECTED;
345 } else if (ConnectState == 2) {
346 ret = MESON_DISCONNECTED;
347 } else {
348 ret = MESON_UNKNOWNCONNECTION;
349 }
350 } else {
limin.tianfe2ab442023-03-06 08:40:15 +0000351 fprintf(stderr, "\n drm open fail\n");
limin.tian20df7d42023-02-10 10:05:52 +0800352 }
353 if (conn)
354 mesonConnectorDestroy(drmFd,conn);
355 return ret;
356}
357
358ENUM_MESON_COLOR_SPACE meson_drm_getColorSpace(int drmFd, MESON_CONNECTOR_TYPE connType )
359{
360 char propName[PROP_NAME_MAX_LEN] = {'\0'};
361 sprintf( propName, "%s", DRM_CONNECTOR_PROP_COLOR_SPACE);
362 uint32_t value = 0;
363 ENUM_MESON_COLOR_SPACE colorSpace = MESON_COLOR_SPACE_RESERVED;
364 if ( drmFd < 0) {
limin.tianfe2ab442023-03-06 08:40:15 +0000365 fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
limin.tian20df7d42023-02-10 10:05:52 +0800366 return colorSpace;
367 }
368 if ( 0 == meson_drm_get_conn_prop_value(drmFd, connType, propName, &value )) {
369 switch (value)
370 {
371 case 0:
372 colorSpace = MESON_COLOR_SPACE_RGB;
373 break;
374 case 1:
375 colorSpace = MESON_COLOR_SPACE_YCBCR422;
376 break;
377 case 2:
378 colorSpace = MESON_COLOR_SPACE_YCBCR444;
379 break;
380 case 3:
381 colorSpace = MESON_COLOR_SPACE_YCBCR420;
382 break;
383 default:
384 colorSpace = MESON_COLOR_SPACE_RESERVED;
385 break;
386 }
387 } else {
limin.tianfe2ab442023-03-06 08:40:15 +0000388 fprintf(stderr, "\n%s %d fail\n",__FUNCTION__,__LINE__);
limin.tian20df7d42023-02-10 10:05:52 +0800389 }
390 return colorSpace;
391}
392int meson_drm_setColorSpace(int drmFd, drmModeAtomicReq *req,
393 ENUM_MESON_COLOR_SPACE colorSpace, MESON_CONNECTOR_TYPE connType)
394{
395 int ret = -1;
396 uint32_t connId = 0;
397 int rc = -1;
398 struct mesonConnector* conn = NULL;
399 if ( drmFd < 0 || req == NULL) {
limin.tianfe2ab442023-03-06 08:40:15 +0000400 fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
limin.tian20df7d42023-02-10 10:05:52 +0800401 return ret;
402 }
403 conn = get_current_connector(drmFd, connType);
404 if (conn) {
405 connId = mesonConnectorGetId(conn);
406 rc = meson_drm_set_property(drmFd, req, connId, DRM_MODE_OBJECT_CONNECTOR,
407 DRM_CONNECTOR_PROP_COLOR_SPACE, (uint64_t)colorSpace);
408 mesonConnectorDestroy(drmFd,conn);
409 }
410 if (rc >= 0)
411 ret = 0;
412 return ret;
413
414}
415
416uint32_t meson_drm_getColorDepth( int drmFd, MESON_CONNECTOR_TYPE connType )
417{
418 char propName[PROP_NAME_MAX_LEN] = {'\0'};
419 sprintf( propName, "%s", DRM_CONNECTOR_PROP_COLOR_DEPTH);
420 uint32_t value = 0;
421 if ( drmFd < 0) {
limin.tianfe2ab442023-03-06 08:40:15 +0000422 fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
limin.tian20df7d42023-02-10 10:05:52 +0800423 return value;
424 }
425 if ( 0 != meson_drm_get_conn_prop_value( drmFd, connType, propName, &value )) {
limin.tianfe2ab442023-03-06 08:40:15 +0000426 fprintf(stderr, "\n%s %d fail\n",__FUNCTION__,__LINE__);
limin.tian20df7d42023-02-10 10:05:52 +0800427 }
428 return value;
429}
430int meson_drm_setColorDepth(int drmFd, drmModeAtomicReq *req,
431 uint32_t colorDepth, MESON_CONNECTOR_TYPE connType)
432{
433 int ret = -1;
434 int rc = -1;
435 struct mesonConnector* conn = NULL;
436 uint32_t connId = 0;
437 conn = get_current_connector(drmFd, connType);
438 if ( drmFd < 0 || req == NULL) {
limin.tianfe2ab442023-03-06 08:40:15 +0000439 fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
limin.tian20df7d42023-02-10 10:05:52 +0800440 return ret;
441 }
442 if (conn) {
443 connId = mesonConnectorGetId(conn);
444 rc = meson_drm_set_property(drmFd, req, connId, DRM_MODE_OBJECT_CONNECTOR,
445 DRM_CONNECTOR_PROP_COLOR_DEPTH, (uint64_t)colorDepth);
446 mesonConnectorDestroy(drmFd,conn);
447 }
448 if (rc >= 0)
449 ret = 0;
450 return ret;
451}
452ENUM_MESON_HDR_POLICY meson_drm_getHDRPolicy( int drmFd, MESON_CONNECTOR_TYPE connType )
453{
454 char propName[PROP_NAME_MAX_LEN] = {'\0'};
455 sprintf( propName, "%s", DRM_CONNECTOR_PROP_TX_HDR_POLICY);
456 uint32_t value = 0;
457 ENUM_MESON_HDR_POLICY hdrPolicy = MESON_HDR_POLICY_FOLLOW_SINK;
458 if ( drmFd < 0) {
limin.tianfe2ab442023-03-06 08:40:15 +0000459 fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
limin.tian20df7d42023-02-10 10:05:52 +0800460 return hdrPolicy;
461 }
462 if ( 0 == meson_drm_get_crtc_prop_value( drmFd, connType, propName, &value )) {
463 if (value == 0)
464 hdrPolicy = MESON_HDR_POLICY_FOLLOW_SINK;
465 if (value == 1)
466 hdrPolicy = MESON_HDR_POLICY_FOLLOW_SOURCE;
467 }
468 return hdrPolicy;
469}
470
471int meson_drm_setHDRPolicy(int drmFd, drmModeAtomicReq *req,
472 ENUM_MESON_HDR_POLICY hdrPolicy, MESON_CONNECTOR_TYPE connType)
473{
474 int ret = -1;
475 int rc = -1;
476 struct mesonConnector* conn = NULL;
477 uint32_t crtcId = 0;
478 conn = get_current_connector(drmFd, connType);
479 if ( drmFd < 0 || req == NULL) {
limin.tianfe2ab442023-03-06 08:40:15 +0000480 fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
limin.tian20df7d42023-02-10 10:05:52 +0800481 return ret;
482 }
483 if (conn) {
484 crtcId = mesonConnectorGetCRTCId(conn);
485 rc = meson_drm_set_property(drmFd, req, crtcId, DRM_MODE_OBJECT_CRTC,
486 DRM_CONNECTOR_PROP_TX_HDR_POLICY, (uint64_t)hdrPolicy);
487 mesonConnectorDestroy(drmFd,conn);
488 }
489 if (rc >= 0)
490 ret = 0;
491 return ret;
492}
493
494ENUM_MESON_HDCP_VERSION meson_drm_getHdcpVersion( int drmFd, MESON_CONNECTOR_TYPE connType )
495{
496 char propName[PROP_NAME_MAX_LEN] = {'\0'};
497 sprintf( propName, "%s", DRM_CONNECTOR_PROP_TX_HDCP_AUTH_MODE);
498 uint32_t value = 0;
499 ENUM_MESON_HDCP_VERSION hdcpVersion = MESON_HDCP_RESERVED;
500 if ( drmFd < 0) {
limin.tianfe2ab442023-03-06 08:40:15 +0000501 fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
limin.tian20df7d42023-02-10 10:05:52 +0800502 return hdcpVersion;
503 }
504 if ( 0 == meson_drm_get_conn_prop_value( drmFd, connType, propName, &value )) {
505 if (value & 0x1)
506 hdcpVersion = MESON_HDCP_14;
507 if (value & 0x2)
508 hdcpVersion = MESON_HDCP_22;
509 }
510 return hdcpVersion;
511}
512
513ENUM_MESON_HDR_MODE meson_drm_getHdrStatus(int drmFd, MESON_CONNECTOR_TYPE connType )
514{
515 char propName[PROP_NAME_MAX_LEN] = {'\0'};
516 sprintf( propName, "%s", DRM_CONNECTOR_PROP_TX_HDR_MODE);
517 uint32_t value = 0;
518 ENUM_MESON_HDR_MODE hdrMode = MESON_SDR;
519 if ( drmFd < 0) {
limin.tianfe2ab442023-03-06 08:40:15 +0000520 fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
limin.tian20df7d42023-02-10 10:05:52 +0800521 return hdrMode;
522 }
523 if ( 0 == meson_drm_get_conn_prop_value( drmFd, connType, propName, &value )) {
524 switch (value)
525 {
526 case 0:
527 hdrMode = MESON_HDR10PLUS;
528 break;
529 case 1:
530 hdrMode = MESON_DOLBYVISION_STD;
531 break;
532 case 2:
533 hdrMode = MESON_DOLBYVISION_LL;
534 break;
535 case 3:
536 hdrMode = MESON_HDR10_ST2084;
537 break;
538 case 4:
539 hdrMode = MESON_HDR10_TRADITIONAL;
540 break;
541 case 5:
542 hdrMode = MESON_HDR_HLG;
543 break;
544 case 6:
545 hdrMode = MESON_SDR;
546 break;
547 default:
548 hdrMode = MESON_SDR;
549 break;
550 }
551 } else {
limin.tianfe2ab442023-03-06 08:40:15 +0000552 fprintf(stderr, "\n%s %d fail\n",__FUNCTION__,__LINE__);
limin.tian20df7d42023-02-10 10:05:52 +0800553 }
554 return hdrMode;
555}
limin.tianfe2ab442023-03-06 08:40:15 +0000556void meson_drm_getEDIDData(int drmFd, MESON_CONNECTOR_TYPE connType, int * data_Len, char **data )
557{
558 int i = 0;
559 int count = 0;
560 char* edid_data = NULL;
561 struct mesonConnector* conn = NULL;
562 if (drmFd < 0 || data_Len == NULL || data == NULL) {
563 fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
564 return;
565 }
566 conn = get_current_connector(drmFd, connType);
567 if (conn == NULL) {
568 fprintf(stderr, "\n%s %d connector create fail.return \n",__FUNCTION__,__LINE__);
569 return;
570 }
571 if (0 != mesonConnectorGetEdidBlob(conn, &count, &edid_data))
572 goto out;
573 char* edid = (char*)calloc(count, sizeof(char));
574 if (edid == NULL) {
575 fprintf(stderr, "\n%s %d edid alloc mem fail.return\n",__FUNCTION__,__LINE__);
576 return;
577 }
578 for (i = 0; i < count; i++)
579 {
580 edid[i] = edid_data[i];
581 }
582 *data_Len = count;
583 *data = edid;
584out:
585 if (conn)
586 mesonConnectorDestroy(drmFd,conn);
587}
588
589int meson_drm_setAVMute(int drmFd, drmModeAtomicReq *req,
590 bool mute, MESON_CONNECTOR_TYPE connType)
591
592{
593 int ret = -1;
594 int rc = -1;
595 struct mesonConnector* conn = NULL;
596 uint32_t connId = 0;
597 if ( drmFd < 0 || req == NULL) {
598 fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
599 return ret;
600 }
601 conn = get_current_connector(drmFd, connType);
602 if (conn) {
603 connId = mesonConnectorGetId(conn);
604 rc = meson_drm_set_property(drmFd, req, connId, DRM_MODE_OBJECT_CONNECTOR,
605 MESON_DRM_HDMITX_PROP_AVMUTE, (uint64_t)mute);
606 mesonConnectorDestroy(drmFd,conn);
607 }
608 if (rc >= 0)
609 ret = 0;
610 return ret;
611}
chen.wang154f11d52023-04-14 07:56:49 +0000612
613int meson_drm_getAVMute( int drmFd, MESON_CONNECTOR_TYPE connType )
614{
615 char propName[PROP_NAME_MAX_LEN] = {'\0'};
616 sprintf( propName, "%s", MESON_DRM_HDMITX_PROP_AVMUTE);
617 uint32_t value = 0;
618 if ( drmFd < 0) {
619 fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
620 return value;
621 }
622 if ( 0 != meson_drm_get_conn_prop_value( drmFd, connType, propName, &value )) {
623 fprintf(stderr, "\n%s %d fail\n",__FUNCTION__,__LINE__);
624 }
625 fprintf(stderr, "\n AVMute control, 1 means set avmute, 0 means not avmute\n");
626 return value;
627}
628
limin.tianfe2ab442023-03-06 08:40:15 +0000629ENUM_MESON_HDCPAUTH_STATUS meson_drm_getHdcpAuthStatus( int drmFd, MESON_CONNECTOR_TYPE connType )
630{
631 char propName[PROP_NAME_MAX_LEN] = {'\0'};
632 sprintf( propName, "%s", DRM_CONNECTOR_PROP_CONTENT_PROTECTION);
633 uint32_t value = 0;
634 ENUM_MESON_HDCPAUTH_STATUS hdcpAuthStatus = MESON_AUTH_STATUS_FAIL;
635 if ( drmFd < 0 ) {
636 fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
637 return hdcpAuthStatus;
638 }
639 if ( 0 == meson_drm_get_conn_prop_value( drmFd, connType, propName, &value )) {
640 if (value == 2)
641 hdcpAuthStatus = MESON_AUTH_STATUS_SUCCESS;
642 }
643 return hdcpAuthStatus;
644}
645
646int meson_drm_setHDCPEnable(int drmFd, drmModeAtomicReq *req,
647 bool enable, MESON_CONNECTOR_TYPE connType)
648
649{
650 int ret = -1;
651 int rc = -1;
652 struct mesonConnector* conn = NULL;
653 uint32_t connId = 0;
654 if ( drmFd < 0 || req == NULL) {
655 fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
656 return ret;
657 }
658 conn = get_current_connector(drmFd, connType);
659 if (conn) {
660 connId = mesonConnectorGetId(conn);
661 rc = meson_drm_set_property(drmFd, req, connId, DRM_MODE_OBJECT_CONNECTOR,
662 DRM_CONNECTOR_PROP_CONTENT_PROTECTION, (uint64_t)enable);
663 mesonConnectorDestroy(drmFd,conn);
664 }
665 if (rc >= 0)
666 ret = 0;
667 return ret;
668}
669
chen.wang154f11d52023-04-14 07:56:49 +0000670int meson_drm_setHDCPContentType(int drmFd, drmModeAtomicReq *req,
671 ENUM_MESON_HDCP_Content_Type HDCPType, MESON_CONNECTOR_TYPE connType)
672{
673 int ret = -1;
674 int rc = -1;
675 struct mesonConnector* conn = NULL;
676 uint32_t connId = 0;
677 if ( drmFd < 0 || req == NULL) {
678 fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
679 return ret;
680 }
681 conn = get_current_connector(drmFd, connType);
682 if (conn) {
683 connId = mesonConnectorGetId(conn);
684 rc = meson_drm_set_property(drmFd, req, connId, DRM_MODE_OBJECT_CONNECTOR,
685 DRM_CONNECTOR_PROP_CONTENT_TYPE, (uint64_t)HDCPType);
686 mesonConnectorDestroy(drmFd,conn);
687 }
688 if (rc >= 0)
689 ret = 0;
690 return ret;
691}
692
693ENUM_MESON_HDCP_Content_Type meson_drm_getHDCPContentType( int drmFd, MESON_CONNECTOR_TYPE connType )
694{
695 char propName[PROP_NAME_MAX_LEN] = {'\0'};
696 sprintf( propName, "%s", DRM_CONNECTOR_PROP_CONTENT_TYPE);
697 uint32_t value = 0;
698 ENUM_MESON_HDCP_Content_Type ContentType = MESON_HDCP_Type_RESERVED;
699 if ( drmFd < 0) {
700 fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
701 return ContentType;
702 }
703 if ( 0 == meson_drm_get_conn_prop_value( drmFd, connType, propName, &value )) {
704 switch (value)
705 {
706 case 0:
707 ContentType = MESON_HDCP_Type0;
708 break;
709 case 1:
710 ContentType = MESON_HDCP_Type1;
711 break;
712 default:
713 ContentType = MESON_HDCP_Type_RESERVED;
714 break;
715 }
716 } else {
717 fprintf(stderr, "\n%s %d fail\n",__FUNCTION__,__LINE__);
718 }
719 return ContentType;
720}
721
722MESON_CONTENT_TYPE meson_drm_getContentType(int drmFd, MESON_CONNECTOR_TYPE connType ) {
723
724 char propName[PROP_NAME_MAX_LEN] = {'\0'};
725 sprintf( propName, "%s", DRM_CONNECTOR_PROP_Content_Type);
726 uint32_t value = 0;
727 MESON_CONTENT_TYPE ContentType = MESON_CONTENT_TYPE_RESERVED;
728 if ( drmFd < 0) {
729 fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
730 return ContentType;
731 }
732 if ( 0 == meson_drm_get_conn_prop_value(drmFd, connType, propName, &value )) {
733 switch (value)
734 {
735 case 0:
736 ContentType = MESON_CONTENT_TYPE_Data;
737 break;
738 case 1:
739 ContentType = MESON_CONTENT_TYPE_Graphics;
740 break;
741 case 2:
742 ContentType = MESON_CONTENT_TYPE_Photo;
743 break;
744 case 3:
745 ContentType = MESON_CONTENT_TYPE_Cinema;
746 break;
747 case 4:
748 ContentType = MESON_CONTENT_TYPE_Game;
749 break;
750 default:
751 ContentType = MESON_CONTENT_TYPE_RESERVED;
752 break;
753 }
754 } else {
755 fprintf(stderr, "\n%s %d fail\n",__FUNCTION__,__LINE__);
756 }
757 return ContentType;
758}
759
760int meson_drm_setDvEnable(int drmFd, drmModeAtomicReq *req,
761 uint32_t dvEnable, MESON_CONNECTOR_TYPE connType)
762{
763 int ret = -1;
764 int rc = -1;
765 struct mesonConnector* conn = NULL;
766 uint32_t crtcId = 0;
767 conn = get_current_connector(drmFd, connType);
768 if ( drmFd < 0 || req == NULL) {
769 fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
770 return ret;
771 }
772 if (conn) {
773 crtcId = mesonConnectorGetCRTCId(conn);
774 rc = meson_drm_set_property(drmFd, req, crtcId, DRM_MODE_OBJECT_CRTC,
775 DRM_CONNECTOR_PROP_DV_ENABLE, (uint64_t)dvEnable);
776 mesonConnectorDestroy(drmFd,conn);
777 }
778 if (rc >= 0)
779 ret = 0;
780 return ret;
781}
782
783int meson_drm_getDvEnable( int drmFd, MESON_CONNECTOR_TYPE connType )
784{
785 char propName[PROP_NAME_MAX_LEN] = {'\0'};
786 sprintf( propName, "%s", DRM_CONNECTOR_PROP_DV_ENABLE);
787 uint32_t value = -1;
788 if ( drmFd < 0) {
789 fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
790 return value;
791 }
792 if ( 0 != meson_drm_get_crtc_prop_value( drmFd, connType, propName, &value )) {
793 fprintf(stderr, "\n%s %d fail\n",__FUNCTION__,__LINE__);
794 }
795 return value;
796}
797
798int meson_drm_setActive(int drmFd, drmModeAtomicReq *req,
799 uint32_t active, MESON_CONNECTOR_TYPE connType)
800{
801 int ret = -1;
802 int rc = -1;
803 struct mesonConnector* conn = NULL;
804 uint32_t crtcId = 0;
805 conn = get_current_connector(drmFd, connType);
806 if ( drmFd < 0 || req == NULL) {
807 fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
808 return ret;
809 }
810 if (conn) {
811 crtcId = mesonConnectorGetCRTCId(conn);
812 rc = meson_drm_set_property(drmFd, req, crtcId, DRM_MODE_OBJECT_CRTC,
813 DRM_CONNECTOR_PROP_ACTIVE, (uint64_t)active);
814 mesonConnectorDestroy(drmFd,conn);
815 }
816 if (rc >= 0)
817 ret = 0;
818 return ret;
819}
820
821int meson_drm_getActive( int drmFd, MESON_CONNECTOR_TYPE connType )
822{
823 char propName[PROP_NAME_MAX_LEN] = {'\0'};
824 sprintf( propName, "%s", DRM_CONNECTOR_PROP_ACTIVE);
825 uint32_t value = 0;
826 if ( drmFd < 0) {
827 fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
828 return value;
829 }
830 if ( 0 != meson_drm_get_crtc_prop_value( drmFd, connType, propName, &value )) {
831 fprintf(stderr, "\n%s %d fail\n",__FUNCTION__,__LINE__);
832 }
833 return value;
834}
835
836int meson_drm_setVrrEnabled(int drmFd, drmModeAtomicReq *req,
837 uint32_t VrrEnable, MESON_CONNECTOR_TYPE connType)
838{
839 int ret = -1;
840 int rc = -1;
841 struct mesonConnector* conn = NULL;
842 uint32_t crtcId = 0;
843 conn = get_current_connector(drmFd, connType);
844 if ( drmFd < 0 || req == NULL) {
845 fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
846 return ret;
847 }
848 if (conn) {
849 crtcId = mesonConnectorGetCRTCId(conn);
850 rc = meson_drm_set_property(drmFd, req, crtcId, DRM_MODE_OBJECT_CRTC,
851 DRM_CONNECTOR_VRR_ENABLED, (uint64_t)VrrEnable);
852 mesonConnectorDestroy(drmFd,conn);
853 }
854 if (rc >= 0)
855 ret = 0;
856 return ret;
857}
858
859int meson_drm_getVrrEnabled( int drmFd, MESON_CONNECTOR_TYPE connType )
860{
861 char propName[PROP_NAME_MAX_LEN] = {'\0'};
862 sprintf( propName, "%s", DRM_CONNECTOR_VRR_ENABLED);
863 uint32_t value = 0;
864 if ( drmFd < 0) {
865 fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
866 return value;
867 }
868 if ( 0 != meson_drm_get_crtc_prop_value( drmFd, connType, propName, &value )) {
869 fprintf(stderr, "\n%s %d fail\n",__FUNCTION__,__LINE__);
870 }
871 return value;
872}
873
874int meson_drm_getHdrCap( int drmFd, MESON_CONNECTOR_TYPE connType )
875{
876 char propName[PROP_NAME_MAX_LEN] = {'\0'};
877 sprintf( propName, "%s", DRM_CONNECTOR_PROP_RX_HDR_CAP);
878 uint32_t value = 0;
879 if ( drmFd < 0) {
880 fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
881 return value;
882 }
883 if ( 0 != meson_drm_get_conn_prop_value( drmFd, connType, propName, &value )) {
884 fprintf(stderr, "\n%s %d fail\n",__FUNCTION__,__LINE__);
885 }
886 fprintf(stderr, "hdr_cap:presents the RX HDR capability [r]\n");
887 return value;
888}
889
890int meson_drm_getDvCap( int drmFd, MESON_CONNECTOR_TYPE connType )
891{
892 char propName[PROP_NAME_MAX_LEN] = {'\0'};
893 sprintf( propName, "%s", DRM_CONNECTOR_PROP_RX_DV_CAP);
894 uint32_t value = 0;
895 if ( drmFd < 0) {
896 fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
897 return value;
898 }
899 if ( 0 != meson_drm_get_conn_prop_value( drmFd, connType, propName, &value )) {
900 fprintf(stderr, "\n%s %d fail\n",__FUNCTION__,__LINE__);
901 }
902 fprintf(stderr, "dv_cap:presents the RX dolbyvision capability, [r] such as std or ll mode \n");
903 return value;
904}
905
limin.tianfe2ab442023-03-06 08:40:15 +0000906
limin.tian20df7d42023-02-10 10:05:52 +0800907