blob: 8ac5f8ab656af0619ec4d0adb2bc82a544916534 [file] [log] [blame]
limin.tian75338482022-06-20 09:27:34 +08001/*
2 * Copyright (c) 2021 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>
limin.tianb3c16ad2022-06-22 14:28:27 +080013#include <errno.h>
14#include <xf86drm.h>
15#include <xf86drmMode.h>
limin.tian75338482022-06-20 09:27:34 +080016#include <linux/string.h>
17#include "libdrm_meson_connector.h"
18#include "libdrm_meson_property.h"
19#include "meson_drm_display.h"
20
21
22#define DEFAULT_CARD "/dev/dri/card0"
23#ifndef XDG_RUNTIME_DIR
24#define XDG_RUNTIME_DIR "/run"
25#endif
limin.tian75338482022-06-20 09:27:34 +080026
27static int meson_drm_setprop(int obj_id, char* prop_name, int prop_value );
limin.tian75338482022-06-20 09:27:34 +080028static uint32_t _getHDRSupportedList(uint64_t hdrlist, uint64_t dvlist);
limin.tianb3c16ad2022-06-22 14:28:27 +080029struct mesonConnector* get_current_connector(int drmFd);
limin.tian75338482022-06-20 09:27:34 +080030
31static int meson_drm_setprop(int obj_id, char* prop_name, int prop_value )
32{
33 int ret = -1;
34 printf(" meson_drm_setprop: obj_id %d, prop_name: %s, prop_value:%d\n",obj_id, prop_name,prop_value);
35 char* xdgRunDir = getenv("XDG_RUNTIME_DIR");
36 if (!xdgRunDir)
37 xdgRunDir = XDG_RUNTIME_DIR;
38 if (prop_name) {
39 do {
40 char cmdBuf[512] = {'\0'};
41 snprintf(cmdBuf, sizeof(cmdBuf)-1, "export XDG_RUNTIME_DIR=%s;westeros-gl-console set property -s %d:%s:%d | grep \"Response\"",
42 xdgRunDir, obj_id, prop_name, prop_value);
43 printf("Executing '%s'\n", cmdBuf);
44 FILE* fp = popen(cmdBuf, "r");
45 if (NULL != fp) {
46 char output[64] = {'\0'};
47 while (fgets(output, sizeof(output)-1, fp)) {
48 if (strlen(output) && strstr(output, "[0:")) {
49 ret = 0;
50 printf("\n meson_drm_setprop:%s\n",output);
51 }
52 }
53 pclose(fp);
54 } else {
55 printf("meson_drm_setprop: popen failed\n");
56 }
57 if (ret != 0 ) {
58 if (strcmp(xdgRunDir, XDG_RUNTIME_DIR) == 0) {
limin.tian75338482022-06-20 09:27:34 +080059 break;
60 }
61 xdgRunDir = XDG_RUNTIME_DIR;
62 }
63 } while (ret != 0);
64 }
65 return ret;
66}
67
limin.tian75338482022-06-20 09:27:34 +080068static uint32_t _getHDRSupportedList(uint64_t hdrlist, uint64_t dvlist)
69{
70 uint32_t ret = 0;
71 printf("\n _getHDRSupportedList hdrlist:%llu, dvlist:%llu\n", hdrlist, dvlist);
72 if (!!(hdrlist & 0x1))
73 ret = ret | (0x1 << (int)MESON_DRM_HDR10PLUS);
74
75 if (!!(dvlist & 0x1A))
76 ret = ret | (0x1 << (int)MESON_DRM_DOLBYVISION_STD);
77
78 if (!!(dvlist & 0xE0))
79 ret = ret | (0x1 << (int)MESON_DRM_DOLBYVISION_LL);
80
81 if (!!(hdrlist & 0x8))
82 ret = ret | (0x1 << (int)MESON_DRM_HDR10_ST2084);
83
84 if (!!(hdrlist & 0x4))
85 ret = ret | (0x1 << (int)MESON_DRM_HDR10_TRADITIONAL);
86
87 if (!!(hdrlist & 0x10))
88 ret = ret | (0x1 << (int)MESON_DRM_HDR_HLG);
89
90 if (!!(hdrlist & 0x2))
91 ret = ret | (0x1 << (int)MESON_DRM_SDR);
92
93 return ret;
94}
95
limin.tianb3c16ad2022-06-22 14:28:27 +080096int meson_drm_setMode(DisplayMode* mode)
limin.tian75338482022-06-20 09:27:34 +080097{
98 int ret = -1;
limin.tianb3c16ad2022-06-22 14:28:27 +080099 char cmdBuf[512] = {'\0'};
100 char output[64] = {'\0'};
101 char modeSet[20] = {'\0'};
limin.tian75338482022-06-20 09:27:34 +0800102 char* xdgRunDir = getenv("XDG_RUNTIME_DIR");
103 if (!xdgRunDir)
104 xdgRunDir = XDG_RUNTIME_DIR;
105 if (!mode) {
106 ret = -1;
107 } else {
limin.tiane709cad2022-07-07 17:07:21 +0800108 sprintf(modeSet, "%dx%d%c%d", mode->w, mode->h, mode->interlace ? 'i':'p',mode->vrefresh);
limin.tian75338482022-06-20 09:27:34 +0800109 do {
110 snprintf(cmdBuf, sizeof(cmdBuf)-1, "export XDG_RUNTIME_DIR=%s;westeros-gl-console set mode %s | grep \"Response\"",
limin.tianb3c16ad2022-06-22 14:28:27 +0800111 xdgRunDir, modeSet);
limin.tian75338482022-06-20 09:27:34 +0800112 printf("Executing '%s'\n", cmdBuf);
113 /* FIXME: popen in use */
114 FILE* fp = popen(cmdBuf, "r");
115 if (NULL != fp) {
116 while (fgets(output, sizeof(output)-1, fp)) {
117 if (strlen(output) && strstr(output, "[0:")) {
118 ret = 0;
119 } else {
120 ret = -1;
121 }
122 }
123 pclose(fp);
124 } else {
125 printf(" popen failed\n");
126 ret = -1;
127 }
128 if (ret != 0 ) {
129 if (strcmp(xdgRunDir, XDG_RUNTIME_DIR) == 0) {
limin.tiane709cad2022-07-07 17:07:21 +0800130 printf("meson_drm_setMode: failed !!\n");
limin.tian75338482022-06-20 09:27:34 +0800131 break;
132 }
133 xdgRunDir = XDG_RUNTIME_DIR;
134 }
135 } while (ret != 0);
136 }
137 return ret;
138}
limin.tianb3c16ad2022-06-22 14:28:27 +0800139int meson_drm_getMode(DisplayMode* modeInfo)
limin.tian75338482022-06-20 09:27:34 +0800140{
limin.tianb3c16ad2022-06-22 14:28:27 +0800141 int ret = -1;
limin.tiane709cad2022-07-07 17:07:21 +0800142 struct mesonConnector* conn = NULL;
143 drmModeModeInfo* mode = NULL;
144 int drmFd = -1;
145 if (modeInfo == NULL) {
146 printf("\n %s %d modeInfo == NULL return\n",__FUNCTION__,__LINE__);
limin.tianb3c16ad2022-06-22 14:28:27 +0800147 return ret;
limin.tiane709cad2022-07-07 17:07:21 +0800148 }
149 drmFd = meson_drm_open();
150 conn = mesonConnectorCreate(drmFd, DRM_MODE_CONNECTOR_HDMIA);
151 if ( conn ) {
152 mode = mesonConnectorGetCurMode(drmFd, conn);
153 if (mode) {
154 modeInfo->w = mode->hdisplay;
155 modeInfo->h = mode->vdisplay;
156 modeInfo->vrefresh = mode->vrefresh;
157 modeInfo->interlace = mode->flags & DRM_MODE_FLAG_INTERLACE;
158 strcpy(modeInfo->name, mode->name);
159 free(mode);
160 mode = NULL;
161 ret = 0;
limin.tian75338482022-06-20 09:27:34 +0800162 } else {
limin.tiane709cad2022-07-07 17:07:21 +0800163 printf("\n %s %d mode get fail \n",__FUNCTION__,__LINE__);
limin.tian75338482022-06-20 09:27:34 +0800164 }
limin.tiane709cad2022-07-07 17:07:21 +0800165 } else {
166 printf("\n %s %d conn create fail \n",__FUNCTION__,__LINE__);
167 }
168 if (conn)
169 mesonConnectorDestroy(drmFd,conn);
170 if (drmFd >= 0 )
171 close(drmFd);
limin.tianb3c16ad2022-06-22 14:28:27 +0800172 return ret;
limin.tian75338482022-06-20 09:27:34 +0800173}
174
limin.tianb3c16ad2022-06-22 14:28:27 +0800175int meson_drm_getRxSurportedModes( DisplayMode** modes, int* modeCount )
limin.tian75338482022-06-20 09:27:34 +0800176{
177 int ret = -1;
limin.tiane709cad2022-07-07 17:07:21 +0800178 int drmFd = -1;
179 struct mesonConnector* conn = NULL;
180 drmFd = meson_drm_open();
181 conn = mesonConnectorCreate(drmFd, DRM_MODE_CONNECTOR_HDMIA);
182 if (conn == NULL || drmFd < 0)
183 {
184 printf("\n%s %d connector create fail\n",__FUNCTION__,__LINE__);
limin.tian75338482022-06-20 09:27:34 +0800185 }
186 drmModeModeInfo* modeall = NULL;
187 int count = 0;
188 int i = 0;
limin.tiane709cad2022-07-07 17:07:21 +0800189 if (0 != mesonConnectorGetModes(conn, drmFd, &modeall, &count))
limin.tian75338482022-06-20 09:27:34 +0800190 goto out;
limin.tianb3c16ad2022-06-22 14:28:27 +0800191 DisplayMode* modestemp = (DisplayMode*)calloc(count, sizeof(DisplayMode));
limin.tian75338482022-06-20 09:27:34 +0800192 for (i = 0; i < count; i++)
193 {
194 modestemp[i].w = modeall[i].hdisplay;
195 modestemp[i].h = modeall[i].vdisplay;
196 modestemp[i].vrefresh = modeall[i].vrefresh;
197 modestemp[i].interlace = (modeall[i].flags & DRM_MODE_FLAG_INTERLACE) ? true : false;
198 strcpy(modestemp[i].name, modeall[i].name );
199 }
200 *modeCount = count;
201 *modes = modestemp;
202 ret = 0;
203out:
limin.tiane709cad2022-07-07 17:07:21 +0800204 if (conn)
205 mesonConnectorDestroy(drmFd,conn);
206 if (drmFd >= 0 )
207 close(drmFd);
limin.tian75338482022-06-20 09:27:34 +0800208 return ret;
209}
limin.tianb3c16ad2022-06-22 14:28:27 +0800210int meson_drm_getRxPreferredMode( DisplayMode* mode)
limin.tian75338482022-06-20 09:27:34 +0800211{
212 int ret = -1;
213 int i = 0;
214 int count = 0;
215 drmModeModeInfo* modes = NULL;
limin.tiane709cad2022-07-07 17:07:21 +0800216 int drmFd = -1;
217 struct mesonConnector* conn = NULL;
218 drmFd = meson_drm_open();
219 conn = mesonConnectorCreate(drmFd, DRM_MODE_CONNECTOR_HDMIA);
220 if (conn == NULL || drmFd < 0)
221 {
222 printf("\n%s %d connector create fail\n",__FUNCTION__,__LINE__);
limin.tian75338482022-06-20 09:27:34 +0800223 }
limin.tiane709cad2022-07-07 17:07:21 +0800224
225 if (0 != mesonConnectorGetModes(conn, drmFd, &modes, &count))
limin.tian75338482022-06-20 09:27:34 +0800226 goto out;
227 for (i = 0; i < count; i++)
228 {
229 if (modes[i].type & DRM_MODE_TYPE_PREFERRED)
230 {
231 mode->w = modes[i].hdisplay;
232 mode->h = modes[i].vdisplay;
233 mode->interlace = (modes[i].flags & DRM_MODE_FLAG_INTERLACE) ? true : false;
234 strcpy(mode->name, modes[i].name );
235 break;
236 }
237 }
238 ret = 0;
239out:
limin.tiane709cad2022-07-07 17:07:21 +0800240 if (conn)
241 mesonConnectorDestroy(drmFd,conn);
242 if (drmFd >= 0 )
243 close(drmFd);
limin.tian75338482022-06-20 09:27:34 +0800244 return ret;
245}
246
247int meson_drm_getEDID( int * data_Len, char **data)
248{
249 int ret = -1;
250 int i = 0;
251 int count = 0;
limin.tian75338482022-06-20 09:27:34 +0800252 char* edid_data = NULL;
limin.tiane709cad2022-07-07 17:07:21 +0800253 int drmFd = -1;
254 struct mesonConnector* conn = NULL;
255 drmFd = meson_drm_open();
256 conn = mesonConnectorCreate(drmFd, DRM_MODE_CONNECTOR_HDMIA);
257 if (conn == NULL || drmFd < 0)
258 {
259 printf("\n%s %d connector create fail\n",__FUNCTION__,__LINE__);
limin.tian75338482022-06-20 09:27:34 +0800260 }
limin.tiane709cad2022-07-07 17:07:21 +0800261 if (0 != mesonConnectorGetEdidBlob(conn, &count, &edid_data))
limin.tian75338482022-06-20 09:27:34 +0800262 goto out;
263 char* edid = (char*)calloc(count, sizeof(char));
264 for (i = 0; i < count; i++)
265 {
266 edid[i] = edid_data[i];
267 }
268 *data_Len = count;
269 *data = edid;
270 ret = 0;
271out:
limin.tiane709cad2022-07-07 17:07:21 +0800272 if (conn)
273 mesonConnectorDestroy(drmFd,conn);
274 if (drmFd >= 0 )
275 close(drmFd);
limin.tian75338482022-06-20 09:27:34 +0800276 return ret;
277}
278
279int meson_drm_getRxSurportedEOTF(ENUM_DRM_HDMITX_PROP_EOTF* EOTFs)
280{
281 //get from EDID
282 return 0;
283}
284
285ENUM_MESON_DRM_CONNECTION meson_drm_getConnection()
286{
287 ENUM_MESON_DRM_CONNECTION ret = MESON_DRM_UNKNOWNCONNECTION;
limin.tiane709cad2022-07-07 17:07:21 +0800288 int drmFd = -1;
289 struct mesonConnector* conn = NULL;
290 drmFd = meson_drm_open();
291 conn = mesonConnectorCreate(drmFd, DRM_MODE_CONNECTOR_HDMIA);
292 if (conn == NULL || drmFd < 0)
293 {
294 printf("\n%s %d connector create fail\n",__FUNCTION__,__LINE__);
295 }
296 if (conn) {
limin.tian75338482022-06-20 09:27:34 +0800297 int ConnectState = -1;
limin.tiane709cad2022-07-07 17:07:21 +0800298 ConnectState = mesonConnectorGetConnectState(conn);
limin.tian75338482022-06-20 09:27:34 +0800299 if (ConnectState == 1) {
300 ret = MESON_DRM_CONNECTED;
301 } else if (ConnectState == 2) {
302 ret = MESON_DRM_DISCONNECTED;
303 } else {
304 ret = MESON_DRM_UNKNOWNCONNECTION;
limin.tian75338482022-06-20 09:27:34 +0800305 }
306 } else {
307 printf("\n drm open fail\n");
308 }
limin.tiane709cad2022-07-07 17:07:21 +0800309 if (conn)
310 mesonConnectorDestroy(drmFd,conn);
311 if (drmFd >= 0 )
312 close(drmFd);
limin.tian75338482022-06-20 09:27:34 +0800313 return ret;
314}
315
316int meson_drm_set_prop( ENUM_MESON_DRM_PROP enProp, int prop_value )
317{
318 int ret = -1;
319 int objID = -1;
320 char propName[50] = {'\0'};
321 bool force1_4 = false;
322 if (enProp >= ENUM_DRM_PROP_MAX) {
323 printf("\n%s %d invalid para\n",__FUNCTION__,__LINE__);
324 goto out;
325 }
limin.tiane709cad2022-07-07 17:07:21 +0800326 int drmFd = -1;
327 struct mesonConnector* conn = NULL;
328 drmFd = meson_drm_open();
329 conn = mesonConnectorCreate(drmFd, DRM_MODE_CONNECTOR_HDMIA);
330 if (conn == NULL || drmFd < 0)
331 {
332 printf("\n%s %d connector create fail\n",__FUNCTION__,__LINE__);
limin.tian75338482022-06-20 09:27:34 +0800333 goto out;
334 }
335 switch (enProp)
336 {
337 case ENUM_DRM_PROP_HDMI_ENABLE:
338 {
limin.tiane709cad2022-07-07 17:07:21 +0800339 objID = mesonConnectorGetId(conn);
limin.tian75338482022-06-20 09:27:34 +0800340 sprintf( propName, "%s", MESON_DRM_HDMITX_PROP_AVMUTE);
341 prop_value = prop_value ? 0:1;
342 break;
343 }
344 case ENUM_DRM_PROP_HDMITX_EOTF:
345 {
limin.tiane709cad2022-07-07 17:07:21 +0800346 objID = mesonConnectorGetCRTCId(conn);
limin.tian75338482022-06-20 09:27:34 +0800347 sprintf( propName, "%s", MESON_DRM_HDMITX_PROP_EOTF);
348 break;
349 }
350 case ENUM_DRM_PROP_CONTENT_PROTECTION:
351 {
limin.tiane709cad2022-07-07 17:07:21 +0800352 objID = mesonConnectorGetId(conn);
limin.tian75338482022-06-20 09:27:34 +0800353 sprintf( propName, "%s", DRM_CONNECTOR_PROP_CONTENT_PROTECTION);
354 break;
355 }
356 case ENUM_DRM_PROP_HDCP_VERSION:
357 {
limin.tiane709cad2022-07-07 17:07:21 +0800358 objID = mesonConnectorGetId(conn);
limin.tian75338482022-06-20 09:27:34 +0800359 sprintf( propName, "%s", DRM_CONNECTOR_PROP_CONTENT_TYPE);
360 if (ENUM_HDCP_VERSION_FORCE_1_4 == prop_value)
361 {
362 prop_value = 0;
363 force1_4 = true;
364 }
365 break;
366 }
367 case ENUM_DRM_PROP_HDR_POLICY:
368 {
limin.tiane709cad2022-07-07 17:07:21 +0800369 objID = mesonConnectorGetCRTCId(conn);
limin.tian75338482022-06-20 09:27:34 +0800370 sprintf( propName, "%s", DRM_CONNECTOR_PROP_TX_HDR_POLICY);
371 break;
372 }
373 case ENUM_DRM_PROP_HDMI_ASPECT_RATIO:
374 {
limin.tiane709cad2022-07-07 17:07:21 +0800375 objID = mesonConnectorGetId(conn);
limin.tian75338482022-06-20 09:27:34 +0800376 sprintf( propName, "%s", DRM_CONNECTOR_PROP_TX_ASPECT_RATIO);
377 break;
378 }
limin.tianb3c16ad2022-06-22 14:28:27 +0800379 case ENUM_DRM_PROP_HDMI_DV_ENABLE:
380 {
limin.tiane709cad2022-07-07 17:07:21 +0800381 objID = mesonConnectorGetCRTCId(conn);
limin.tianb3c16ad2022-06-22 14:28:27 +0800382 sprintf( propName, "%s", DRM_CONNECTOR_PROP_DV_ENABLE);
383 }
limin.tian75338482022-06-20 09:27:34 +0800384 default:
385 break;
386 }
387 meson_drm_setprop(objID, propName, prop_value);
388 if (enProp == ENUM_DRM_PROP_HDCP_VERSION)
389 {
limin.tiane709cad2022-07-07 17:07:21 +0800390 objID = mesonConnectorGetId(conn);
limin.tian75338482022-06-20 09:27:34 +0800391 sprintf( propName, "%s", DRM_CONNECTOR_PROP_HDCP_PRIORITY);
392 int priority = 0;
393 if (force1_4)
394 {
395 priority = 1;
396 }
397 meson_drm_setprop(objID, propName, priority);
398 }
limin.tian75338482022-06-20 09:27:34 +0800399 ret = 0;
400out:
limin.tiane709cad2022-07-07 17:07:21 +0800401 if (conn)
402 mesonConnectorDestroy(drmFd,conn);
403 if (drmFd >= 0 )
404 close(drmFd);
limin.tian75338482022-06-20 09:27:34 +0800405 return ret;
406}
407
408int meson_drm_get_prop( ENUM_MESON_DRM_PROP enProp, uint32_t* prop_value )
409{
410 int ret = -1;
411 int objID = -1;
412 int objtype = -1;
413 char propName[50] = {'\0'};
414 if (!prop_value || enProp >= ENUM_DRM_PROP_MAX) {
415 printf("\n%s %d invalid para\n",__FUNCTION__,__LINE__);
416 goto out;
417 }
limin.tiane709cad2022-07-07 17:07:21 +0800418 int drmFd = -1;
419 struct mesonConnector* conn = NULL;
420 drmFd = meson_drm_open();
421 conn = mesonConnectorCreate(drmFd, DRM_MODE_CONNECTOR_HDMIA);
422 if (conn == NULL || drmFd < 0)
423 {
424 printf("\n%s %d connector create fail\n",__FUNCTION__,__LINE__);
limin.tian75338482022-06-20 09:27:34 +0800425 goto out;
426 }
427 switch (enProp)
428 {
429 case ENUM_DRM_PROP_HDMI_ENABLE:
430 {
limin.tiane709cad2022-07-07 17:07:21 +0800431 objID = mesonConnectorGetId(conn);
limin.tian75338482022-06-20 09:27:34 +0800432 objtype = DRM_MODE_OBJECT_CONNECTOR;
433 sprintf( propName, "%s", MESON_DRM_HDMITX_PROP_AVMUTE);
434 break;
435 }
436 case ENUM_DRM_PROP_HDMITX_EOTF:
437 {
limin.tiane709cad2022-07-07 17:07:21 +0800438 objID = mesonConnectorGetCRTCId(conn);
limin.tian75338482022-06-20 09:27:34 +0800439 objtype = DRM_MODE_OBJECT_CRTC;
440 sprintf( propName, "%s", MESON_DRM_HDMITX_PROP_EOTF);
441 break;
442 }
443 case ENUM_DRM_PROP_CONTENT_PROTECTION:
444 {
limin.tiane709cad2022-07-07 17:07:21 +0800445 objID = mesonConnectorGetId(conn);
limin.tian75338482022-06-20 09:27:34 +0800446 objtype = DRM_MODE_OBJECT_CONNECTOR;
447 sprintf( propName, "%s", DRM_CONNECTOR_PROP_CONTENT_PROTECTION);
448 break;
449 }
450 case ENUM_DRM_PROP_HDCP_VERSION:
451 {
limin.tiane709cad2022-07-07 17:07:21 +0800452 objID = mesonConnectorGetId(conn);
limin.tian75338482022-06-20 09:27:34 +0800453 objtype = DRM_MODE_OBJECT_CONNECTOR;
454 sprintf( propName, "%s", DRM_CONNECTOR_PROP_CONTENT_TYPE);
455 break;
456 }
457 case ENUM_DRM_PROP_HDR_POLICY:
458 {
limin.tiane709cad2022-07-07 17:07:21 +0800459 objID = mesonConnectorGetCRTCId(conn);
limin.tian75338482022-06-20 09:27:34 +0800460 sprintf( propName, "%s", DRM_CONNECTOR_PROP_TX_HDR_POLICY);
461 objtype = DRM_MODE_OBJECT_CRTC;
462 break;
463 }
464 case ENUM_DRM_PROP_GETRX_HDCP_SUPPORTED_VERS:
465 {
limin.tiane709cad2022-07-07 17:07:21 +0800466 objID = mesonConnectorGetId(conn);
limin.tian75338482022-06-20 09:27:34 +0800467 objtype = DRM_MODE_OBJECT_CONNECTOR;
468 sprintf( propName, "%s", DRM_CONNECTOR_PROP_RX_HDCP_SUPPORTED_VER);
469 break;
470 }
471 case ENUM_DRM_PROP_GETRX_HDR_CAP:
472 {
limin.tiane709cad2022-07-07 17:07:21 +0800473 objID = mesonConnectorGetId(conn);
limin.tian75338482022-06-20 09:27:34 +0800474 objtype = DRM_MODE_OBJECT_CONNECTOR;
475 sprintf( propName, "%s", DRM_CONNECTOR_PROP_RX_HDR_CAP);
476 break;
477 }
478 case ENUM_DRM_PROP_GETTX_HDR_MODE:
479 {
limin.tiane709cad2022-07-07 17:07:21 +0800480 objID = mesonConnectorGetId(conn);
limin.tian75338482022-06-20 09:27:34 +0800481 objtype = DRM_MODE_OBJECT_CONNECTOR;
482 sprintf( propName, "%s", DRM_CONNECTOR_PROP_TX_HDR_MODE);
483 break;
484 }
485 case ENUM_DRM_PROP_HDMI_ASPECT_RATIO:
486 {
limin.tiane709cad2022-07-07 17:07:21 +0800487 objID = mesonConnectorGetId(conn);
limin.tian75338482022-06-20 09:27:34 +0800488 objtype = DRM_MODE_OBJECT_CONNECTOR;
489 sprintf( propName, "%s", DRM_CONNECTOR_PROP_TX_ASPECT_RATIO);
490 break;
491 }
limin.tianb3c16ad2022-06-22 14:28:27 +0800492 case ENUM_DRM_PROP_HDMI_DV_ENABLE:
493 {
limin.tiane709cad2022-07-07 17:07:21 +0800494 objID = mesonConnectorGetCRTCId(conn);
limin.tianb3c16ad2022-06-22 14:28:27 +0800495 objtype = DRM_MODE_OBJECT_CRTC;
496 sprintf( propName, "%s", DRM_CONNECTOR_PROP_DV_ENABLE);
limin.tiane709cad2022-07-07 17:07:21 +0800497 break;
498 }
499 case ENUM_DRM_PROP_GETRX_HDCP_AUTHMODE:
500 {
501 objID = mesonConnectorGetId(conn);
502 objtype = DRM_MODE_OBJECT_CONNECTOR;
503 sprintf( propName, "%s", DRM_CONNECTOR_PROP_TX_HDCP_AUTH_MODE);
504 break;
limin.tianb3c16ad2022-06-22 14:28:27 +0800505 }
limin.tian75338482022-06-20 09:27:34 +0800506 default:
507 break;
508 }
509 struct mesonProperty* meson_prop = NULL;
limin.tiane709cad2022-07-07 17:07:21 +0800510 meson_prop = mesonPropertyCreate(drmFd, objID, objtype, propName);
limin.tian75338482022-06-20 09:27:34 +0800511 if (!meson_prop) {
512 printf("\n meson_prop create fail\n");
513 goto out;
514 }
515 uint64_t value = mesonPropertyGetValue(meson_prop);
516 printf("\n prop value:%llu objID:%d,name:%s\n",value, objID,propName);
517 if (enProp == ENUM_DRM_PROP_HDMI_ENABLE)
518 value = value ? 0:1;
519 *prop_value = (uint32_t)value;
520
521 if (enProp == ENUM_DRM_PROP_GETRX_HDR_CAP)
522 {
limin.tiane709cad2022-07-07 17:07:21 +0800523 objID = mesonConnectorGetId(conn);
limin.tian75338482022-06-20 09:27:34 +0800524 objtype = DRM_MODE_OBJECT_CONNECTOR;
525 sprintf( propName, "%s", DRM_CONNECTOR_PROP_RX_DV_CAP);
526 struct mesonProperty* meson_prop_dv = NULL;
limin.tiane709cad2022-07-07 17:07:21 +0800527 meson_prop_dv = mesonPropertyCreate(drmFd, objID, objtype, propName);
limin.tian75338482022-06-20 09:27:34 +0800528 uint64_t value_2 = mesonPropertyGetValue(meson_prop_dv);
529 mesonPropertyDestroy(meson_prop_dv);
530 *prop_value = _getHDRSupportedList(value, value_2);
531 }
532 if (enProp == ENUM_DRM_PROP_GETRX_HDCP_SUPPORTED_VERS)
533 {
534 *prop_value = 0;
535 if (value == 14)
536 *prop_value = 0x1 << 0;
537 if (value == 22)
538 *prop_value = 0x1 << 1;
539 if (value == 36)
540 *prop_value = 0x1 | (0x1 << 1);
541 }
542 if (enProp == ENUM_DRM_PROP_HDCP_VERSION)
543 {
544 if (*prop_value == 0)
545 {
limin.tiane709cad2022-07-07 17:07:21 +0800546 objID = mesonConnectorGetId(conn);
limin.tian75338482022-06-20 09:27:34 +0800547 objtype = DRM_MODE_OBJECT_CONNECTOR;
548 sprintf( propName, "%s", DRM_CONNECTOR_PROP_HDCP_PRIORITY);
549 struct mesonProperty* meson_prop_HDCP = NULL;
limin.tiane709cad2022-07-07 17:07:21 +0800550 meson_prop_HDCP = mesonPropertyCreate(drmFd, objID, objtype, propName);
limin.tian75338482022-06-20 09:27:34 +0800551 uint64_t value_3 = mesonPropertyGetValue(meson_prop_HDCP);
552 mesonPropertyDestroy(meson_prop_HDCP);
553 printf("\n prop value:%llu objID:%d,name:%s\n",value_3, objID,propName);
554 if (value_3 == 1)
555 *prop_value = 2;
556 }
557 }
558 mesonPropertyDestroy(meson_prop);
limin.tian75338482022-06-20 09:27:34 +0800559 ret = 0;
560out:
limin.tiane709cad2022-07-07 17:07:21 +0800561 if (conn)
562 mesonConnectorDestroy(drmFd,conn);
563 if (drmFd >= 0 )
564 close(drmFd);
limin.tian75338482022-06-20 09:27:34 +0800565 return ret;
566}
567
limin.tianb3c16ad2022-06-22 14:28:27 +0800568int meson_drm_open()
569{
570 int ret_fd = -1;
571 const char *card;
572 card= getenv("WESTEROS_DRM_CARD");
573 if ( !card ) {
574 card = DEFAULT_CARD;
575 }
576 ret_fd = open(card, O_RDONLY|O_CLOEXEC);
577 if ( ret_fd < 0 )
578 printf("\n drm card:%s open fail\n",card);
579 return ret_fd;
580}
581struct mesonConnector* get_current_connector(int drmFd)
582{
583 struct mesonConnector* connectorHDMI = NULL;
584 struct mesonConnector* connectorTV = NULL;
585 int HDMIconnected = 0;
586 connectorHDMI = mesonConnectorCreate(drmFd, DRM_MODE_CONNECTOR_HDMIA);
587 HDMIconnected = mesonConnectorGetConnectState(connectorHDMI);
588 if (HDMIconnected == 1) {
589 return connectorHDMI;
590 } else {
591 connectorTV = mesonConnectorCreate(drmFd, DRM_MODE_CONNECTOR_LVDS);
592 return connectorTV;
593 }
594}
limin.tian75338482022-06-20 09:27:34 +0800595
limin.tianb3c16ad2022-06-22 14:28:27 +0800596void meson_drm_close_fd(int drmFd)
597{
598 if (drmFd >= 0)
limin.tiane709cad2022-07-07 17:07:21 +0800599 close(drmFd);
limin.tianb3c16ad2022-06-22 14:28:27 +0800600}
601
602int meson_drm_get_vblank_time(int drmFd, int nextVsync,uint64_t *vblankTime, uint64_t *refreshInterval)
603{
604 int ret = -1;
605 int rc = -1;
606 struct mesonConnector* connector = NULL;
607 drmModeModeInfo* mode = NULL;
608 if (drmFd < 0) {
609 printf("\n drmFd error\n");
610 goto out;
611 }
612 if (nextVsync < 0)
613 nextVsync = 0;
614 connector = get_current_connector(drmFd);
615 if (connector != NULL ) {
616 mode = mesonConnectorGetCurMode(drmFd, connector);
617 if (mode) {
618 *refreshInterval = (1000000LL+(mode->vrefresh/2))/mode->vrefresh;
619 free(mode);
620 ret = 0;
621 }
622 }
623 drmVBlank vbl;
624 vbl.request.type= DRM_VBLANK_RELATIVE;
625 vbl.request.sequence= nextVsync;
626 vbl.request.signal= 0;
627 rc = drmWaitVBlank(drmFd, &vbl );
628 if (rc != 0 ) {
629 printf("drmWaitVBlank failed: rc %d errno %d",rc, errno);
630 goto out;
631 }
632 if ((rc == 0) && (vbl.reply.tval_sec > 0 || vbl.reply.tval_usec > 0)) {
633 *vblankTime = vbl.reply.tval_sec * 1000000LL + vbl.reply.tval_usec;
634 }
635out:
636 mesonConnectorDestroy(drmFd, connector);
637 return ret;
638}
limin.tian75338482022-06-20 09:27:34 +0800639