blob: c6ba6205910d24edd58c7ccb1c77638038b4027d [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
26static int s_drm_fd = -1;
27struct mesonConnector* s_conn_HDMI = NULL;
28
29static int meson_drm_setprop(int obj_id, char* prop_name, int prop_value );
30static bool meson_drm_init();
31static void meson_drm_deinit();
32static uint32_t _getHDRSupportedList(uint64_t hdrlist, uint64_t dvlist);
limin.tianb3c16ad2022-06-22 14:28:27 +080033struct mesonConnector* get_current_connector(int drmFd);
limin.tian75338482022-06-20 09:27:34 +080034
35static int meson_drm_setprop(int obj_id, char* prop_name, int prop_value )
36{
37 int ret = -1;
38 printf(" meson_drm_setprop: obj_id %d, prop_name: %s, prop_value:%d\n",obj_id, prop_name,prop_value);
39 char* xdgRunDir = getenv("XDG_RUNTIME_DIR");
40 if (!xdgRunDir)
41 xdgRunDir = XDG_RUNTIME_DIR;
42 if (prop_name) {
43 do {
44 char cmdBuf[512] = {'\0'};
45 snprintf(cmdBuf, sizeof(cmdBuf)-1, "export XDG_RUNTIME_DIR=%s;westeros-gl-console set property -s %d:%s:%d | grep \"Response\"",
46 xdgRunDir, obj_id, prop_name, prop_value);
47 printf("Executing '%s'\n", cmdBuf);
48 FILE* fp = popen(cmdBuf, "r");
49 if (NULL != fp) {
50 char output[64] = {'\0'};
51 while (fgets(output, sizeof(output)-1, fp)) {
52 if (strlen(output) && strstr(output, "[0:")) {
53 ret = 0;
54 printf("\n meson_drm_setprop:%s\n",output);
55 }
56 }
57 pclose(fp);
58 } else {
59 printf("meson_drm_setprop: popen failed\n");
60 }
61 if (ret != 0 ) {
62 if (strcmp(xdgRunDir, XDG_RUNTIME_DIR) == 0) {
63 printf("meson_drm_setprop: failed !!\n");
64 break;
65 }
66 xdgRunDir = XDG_RUNTIME_DIR;
67 }
68 } while (ret != 0);
69 }
70 return ret;
71}
72
73static bool meson_drm_init()
74{
75 bool ret = false;
76 const char *card;
limin.tian75338482022-06-20 09:27:34 +080077 card= getenv("WESTEROS_DRM_CARD");
78 if ( !card ) {
79 card = DEFAULT_CARD;
80 }
81 s_drm_fd = open(card, O_RDONLY|O_CLOEXEC);
82 if ( s_drm_fd < 0 ) {
83 printf("\n drm card:%s open fail\n",card);
84 ret = false;
85 goto exit;
86 }
87 s_conn_HDMI = mesonConnectorCreate(s_drm_fd, DRM_MODE_CONNECTOR_HDMIA);
88 if ( !s_conn_HDMI ) {
89 printf("\n create HDMI connector fail\n");
90 ret = false;
91 goto exit;
92 }
93 ret = true;
94exit:
95 return ret;
96}
97
98static void meson_drm_deinit()
99{
100 if (s_conn_HDMI)
101 mesonConnectorDestroy(s_drm_fd,s_conn_HDMI);
102 if (s_drm_fd >= 0 )
103 close(s_drm_fd);
104}
105static uint32_t _getHDRSupportedList(uint64_t hdrlist, uint64_t dvlist)
106{
107 uint32_t ret = 0;
108 printf("\n _getHDRSupportedList hdrlist:%llu, dvlist:%llu\n", hdrlist, dvlist);
109 if (!!(hdrlist & 0x1))
110 ret = ret | (0x1 << (int)MESON_DRM_HDR10PLUS);
111
112 if (!!(dvlist & 0x1A))
113 ret = ret | (0x1 << (int)MESON_DRM_DOLBYVISION_STD);
114
115 if (!!(dvlist & 0xE0))
116 ret = ret | (0x1 << (int)MESON_DRM_DOLBYVISION_LL);
117
118 if (!!(hdrlist & 0x8))
119 ret = ret | (0x1 << (int)MESON_DRM_HDR10_ST2084);
120
121 if (!!(hdrlist & 0x4))
122 ret = ret | (0x1 << (int)MESON_DRM_HDR10_TRADITIONAL);
123
124 if (!!(hdrlist & 0x10))
125 ret = ret | (0x1 << (int)MESON_DRM_HDR_HLG);
126
127 if (!!(hdrlist & 0x2))
128 ret = ret | (0x1 << (int)MESON_DRM_SDR);
129
130 return ret;
131}
132
limin.tianb3c16ad2022-06-22 14:28:27 +0800133int meson_drm_setMode(DisplayMode* mode)
limin.tian75338482022-06-20 09:27:34 +0800134{
135 int ret = -1;
limin.tianb3c16ad2022-06-22 14:28:27 +0800136 char cmdBuf[512] = {'\0'};
137 char output[64] = {'\0'};
138 char modeSet[20] = {'\0'};
limin.tian75338482022-06-20 09:27:34 +0800139 char* xdgRunDir = getenv("XDG_RUNTIME_DIR");
140 if (!xdgRunDir)
141 xdgRunDir = XDG_RUNTIME_DIR;
142 if (!mode) {
143 ret = -1;
144 } else {
limin.tianb3c16ad2022-06-22 14:28:27 +0800145 sprintf(modeSet, "%dx%d%cx%d", mode->w, mode->h, mode->interlace ? 'i':'p',mode->vrefresh);
limin.tian75338482022-06-20 09:27:34 +0800146 do {
147 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 +0800148 xdgRunDir, modeSet);
limin.tian75338482022-06-20 09:27:34 +0800149 printf("Executing '%s'\n", cmdBuf);
150 /* FIXME: popen in use */
151 FILE* fp = popen(cmdBuf, "r");
152 if (NULL != fp) {
153 while (fgets(output, sizeof(output)-1, fp)) {
154 if (strlen(output) && strstr(output, "[0:")) {
155 ret = 0;
156 } else {
157 ret = -1;
158 }
159 }
160 pclose(fp);
161 } else {
162 printf(" popen failed\n");
163 ret = -1;
164 }
165 if (ret != 0 ) {
166 if (strcmp(xdgRunDir, XDG_RUNTIME_DIR) == 0) {
167 printf("meson_drm_setprop: failed !!\n");
168 break;
169 }
170 xdgRunDir = XDG_RUNTIME_DIR;
171 }
172 } while (ret != 0);
173 }
174 return ret;
175}
limin.tianb3c16ad2022-06-22 14:28:27 +0800176int meson_drm_getMode(DisplayMode* modeInfo)
limin.tian75338482022-06-20 09:27:34 +0800177{
limin.tianb3c16ad2022-06-22 14:28:27 +0800178 int ret = -1;
limin.tian75338482022-06-20 09:27:34 +0800179 char cmdBuf[512] = {'\0'};
180 char output[64] = {'\0'};
181 char* mode = NULL;
limin.tian75338482022-06-20 09:27:34 +0800182 int temp = -1;
limin.tianb3c16ad2022-06-22 14:28:27 +0800183 int w = 0, h = 0,refresh = 0;
184 char interlace = '\0';
185 char* xdgRunDir = getenv("XDG_RUNTIME_DIR");
186 if (modeInfo == NULL)
187 return ret;
188
limin.tian75338482022-06-20 09:27:34 +0800189 if (!xdgRunDir)
190 xdgRunDir = XDG_RUNTIME_DIR;
191 do {
192 snprintf(cmdBuf, sizeof(cmdBuf)-1, "export XDG_RUNTIME_DIR=%s;westeros-gl-console get mode | grep \"Response\"",
193 xdgRunDir);
194 printf("Executing '%s'\n", cmdBuf);
195 /* FIXME: popen in use */
196 FILE* fp = popen(cmdBuf, "r");
197 if (NULL != fp) {
198 while (fgets(output, sizeof(output)-1, fp)) {
199 if (strlen(output) && strstr(output, "[0:")) {
200 mode = strstr(output, "[0:");
limin.tianb3c16ad2022-06-22 14:28:27 +0800201 sscanf(mode, "[0: mode %dx%d%cx%d]",&w, &h, &interlace, &refresh);
202 printf("\n mode: %dx%d%cx%d\n", w, h, interlace, refresh);
limin.tian75338482022-06-20 09:27:34 +0800203 temp = 0;
limin.tianb3c16ad2022-06-22 14:28:27 +0800204 modeInfo->w = w;
205 modeInfo->h = h;
206 modeInfo->vrefresh = refresh;
207 if (interlace == 'i')
208 modeInfo->interlace = true;
209 else
210 modeInfo->interlace = false;
211 ret = 0;
limin.tian75338482022-06-20 09:27:34 +0800212 }
213 }
214 pclose(fp);
215 } else {
216 printf(" popen failed\n");
217 }
218 if (temp != 0 ) {
limin.tianb3c16ad2022-06-22 14:28:27 +0800219 if (strcmp(xdgRunDir, XDG_RUNTIME_DIR) == 0) {
220 printf("meson_drm_setprop: failed !!\n");
221 break;
222 }
223 xdgRunDir = XDG_RUNTIME_DIR;
limin.tian75338482022-06-20 09:27:34 +0800224 }
225 } while ( temp != 0 );
limin.tianb3c16ad2022-06-22 14:28:27 +0800226 return ret;
limin.tian75338482022-06-20 09:27:34 +0800227}
228
limin.tianb3c16ad2022-06-22 14:28:27 +0800229int meson_drm_getRxSurportedModes( DisplayMode** modes, int* modeCount )
limin.tian75338482022-06-20 09:27:34 +0800230{
231 int ret = -1;
232 if (!meson_drm_init()) {
233 printf("\n drm card open fail\n");
234 goto out;
235 }
236 drmModeModeInfo* modeall = NULL;
237 int count = 0;
238 int i = 0;
239 if (0 != mesonConnectorGetModes(s_conn_HDMI, s_drm_fd, &modeall, &count))
240 goto out;
limin.tianb3c16ad2022-06-22 14:28:27 +0800241 DisplayMode* modestemp = (DisplayMode*)calloc(count, sizeof(DisplayMode));
limin.tian75338482022-06-20 09:27:34 +0800242 for (i = 0; i < count; i++)
243 {
244 modestemp[i].w = modeall[i].hdisplay;
245 modestemp[i].h = modeall[i].vdisplay;
246 modestemp[i].vrefresh = modeall[i].vrefresh;
247 modestemp[i].interlace = (modeall[i].flags & DRM_MODE_FLAG_INTERLACE) ? true : false;
248 strcpy(modestemp[i].name, modeall[i].name );
249 }
250 *modeCount = count;
251 *modes = modestemp;
252 ret = 0;
253out:
254 meson_drm_deinit();
255 return ret;
256}
limin.tianb3c16ad2022-06-22 14:28:27 +0800257int meson_drm_getRxPreferredMode( DisplayMode* mode)
limin.tian75338482022-06-20 09:27:34 +0800258{
259 int ret = -1;
260 int i = 0;
261 int count = 0;
262 drmModeModeInfo* modes = NULL;
263 if (!meson_drm_init()) {
264 printf("\n drm card open fail\n");
265 goto out;
266 }
267 if (0 != mesonConnectorGetModes(s_conn_HDMI, s_drm_fd, &modes, &count))
268 goto out;
269 for (i = 0; i < count; i++)
270 {
271 if (modes[i].type & DRM_MODE_TYPE_PREFERRED)
272 {
273 mode->w = modes[i].hdisplay;
274 mode->h = modes[i].vdisplay;
275 mode->interlace = (modes[i].flags & DRM_MODE_FLAG_INTERLACE) ? true : false;
276 strcpy(mode->name, modes[i].name );
277 break;
278 }
279 }
280 ret = 0;
281out:
282 meson_drm_deinit();
283 return ret;
284}
285
286int meson_drm_getEDID( int * data_Len, char **data)
287{
288 int ret = -1;
289 int i = 0;
290 int count = 0;
limin.tian75338482022-06-20 09:27:34 +0800291 char* edid_data = NULL;
292 if (!meson_drm_init()) {
293 printf("\n drm card open fail\n");
294 goto out;
295 }
296 if (0 != mesonConnectorGetEdidBlob(s_conn_HDMI, &count, &edid_data))
297 goto out;
298 char* edid = (char*)calloc(count, sizeof(char));
299 for (i = 0; i < count; i++)
300 {
301 edid[i] = edid_data[i];
302 }
303 *data_Len = count;
304 *data = edid;
305 ret = 0;
306out:
307 meson_drm_deinit();
308 return ret;
309}
310
311int meson_drm_getRxSurportedEOTF(ENUM_DRM_HDMITX_PROP_EOTF* EOTFs)
312{
313 //get from EDID
314 return 0;
315}
316
317ENUM_MESON_DRM_CONNECTION meson_drm_getConnection()
318{
319 ENUM_MESON_DRM_CONNECTION ret = MESON_DRM_UNKNOWNCONNECTION;
320 if (meson_drm_init()) {
321 int ConnectState = -1;
322 ConnectState = mesonConnectorGetConnectState(s_conn_HDMI);
323 if (ConnectState == 1) {
324 ret = MESON_DRM_CONNECTED;
325 } else if (ConnectState == 2) {
326 ret = MESON_DRM_DISCONNECTED;
327 } else {
328 ret = MESON_DRM_UNKNOWNCONNECTION;
329 meson_drm_deinit();
330 }
331 } else {
332 printf("\n drm open fail\n");
333 }
334 return ret;
335}
336
337int meson_drm_set_prop( ENUM_MESON_DRM_PROP enProp, int prop_value )
338{
339 int ret = -1;
340 int objID = -1;
341 char propName[50] = {'\0'};
342 bool force1_4 = false;
343 if (enProp >= ENUM_DRM_PROP_MAX) {
344 printf("\n%s %d invalid para\n",__FUNCTION__,__LINE__);
345 goto out;
346 }
347 if (!meson_drm_init()) {
348 printf("\n drm card open fail\n");
349 goto out;
350 }
351 switch (enProp)
352 {
353 case ENUM_DRM_PROP_HDMI_ENABLE:
354 {
355 objID = mesonConnectorGetId(s_conn_HDMI);
356 sprintf( propName, "%s", MESON_DRM_HDMITX_PROP_AVMUTE);
357 prop_value = prop_value ? 0:1;
358 break;
359 }
360 case ENUM_DRM_PROP_HDMITX_EOTF:
361 {
362 objID = mesonConnectorGetCRTCId(s_conn_HDMI);
363 sprintf( propName, "%s", MESON_DRM_HDMITX_PROP_EOTF);
364 break;
365 }
366 case ENUM_DRM_PROP_CONTENT_PROTECTION:
367 {
368 objID = mesonConnectorGetId(s_conn_HDMI);
369 sprintf( propName, "%s", DRM_CONNECTOR_PROP_CONTENT_PROTECTION);
370 break;
371 }
372 case ENUM_DRM_PROP_HDCP_VERSION:
373 {
374 objID = mesonConnectorGetId(s_conn_HDMI);
375 sprintf( propName, "%s", DRM_CONNECTOR_PROP_CONTENT_TYPE);
376 if (ENUM_HDCP_VERSION_FORCE_1_4 == prop_value)
377 {
378 prop_value = 0;
379 force1_4 = true;
380 }
381 break;
382 }
383 case ENUM_DRM_PROP_HDR_POLICY:
384 {
385 objID = mesonConnectorGetCRTCId(s_conn_HDMI);
386 sprintf( propName, "%s", DRM_CONNECTOR_PROP_TX_HDR_POLICY);
387 break;
388 }
389 case ENUM_DRM_PROP_HDMI_ASPECT_RATIO:
390 {
391 objID = mesonConnectorGetId(s_conn_HDMI);
392 sprintf( propName, "%s", DRM_CONNECTOR_PROP_TX_ASPECT_RATIO);
393 break;
394 }
limin.tianb3c16ad2022-06-22 14:28:27 +0800395 case ENUM_DRM_PROP_HDMI_DV_ENABLE:
396 {
397 objID = mesonConnectorGetCRTCId(s_conn_HDMI);
398 sprintf( propName, "%s", DRM_CONNECTOR_PROP_DV_ENABLE);
399 }
limin.tian75338482022-06-20 09:27:34 +0800400 default:
401 break;
402 }
403 meson_drm_setprop(objID, propName, prop_value);
404 if (enProp == ENUM_DRM_PROP_HDCP_VERSION)
405 {
406 objID = mesonConnectorGetId(s_conn_HDMI);
407 sprintf( propName, "%s", DRM_CONNECTOR_PROP_HDCP_PRIORITY);
408 int priority = 0;
409 if (force1_4)
410 {
411 priority = 1;
412 }
413 meson_drm_setprop(objID, propName, priority);
414 }
415 meson_drm_deinit();
416 ret = 0;
417out:
418 return ret;
419}
420
421int meson_drm_get_prop( ENUM_MESON_DRM_PROP enProp, uint32_t* prop_value )
422{
423 int ret = -1;
424 int objID = -1;
425 int objtype = -1;
426 char propName[50] = {'\0'};
427 if (!prop_value || enProp >= ENUM_DRM_PROP_MAX) {
428 printf("\n%s %d invalid para\n",__FUNCTION__,__LINE__);
429 goto out;
430 }
431 if (!meson_drm_init()) {
432 printf("\n drm card open fail\n");
433 goto out;
434 }
435 switch (enProp)
436 {
437 case ENUM_DRM_PROP_HDMI_ENABLE:
438 {
439 objID = mesonConnectorGetId(s_conn_HDMI);
440 objtype = DRM_MODE_OBJECT_CONNECTOR;
441 sprintf( propName, "%s", MESON_DRM_HDMITX_PROP_AVMUTE);
442 break;
443 }
444 case ENUM_DRM_PROP_HDMITX_EOTF:
445 {
446 objID = mesonConnectorGetCRTCId(s_conn_HDMI);
447 objtype = DRM_MODE_OBJECT_CRTC;
448 sprintf( propName, "%s", MESON_DRM_HDMITX_PROP_EOTF);
449 break;
450 }
451 case ENUM_DRM_PROP_CONTENT_PROTECTION:
452 {
453 objID = mesonConnectorGetId(s_conn_HDMI);
454 objtype = DRM_MODE_OBJECT_CONNECTOR;
455 sprintf( propName, "%s", DRM_CONNECTOR_PROP_CONTENT_PROTECTION);
456 break;
457 }
458 case ENUM_DRM_PROP_HDCP_VERSION:
459 {
460 objID = mesonConnectorGetId(s_conn_HDMI);
461 objtype = DRM_MODE_OBJECT_CONNECTOR;
462 sprintf( propName, "%s", DRM_CONNECTOR_PROP_CONTENT_TYPE);
463 break;
464 }
465 case ENUM_DRM_PROP_HDR_POLICY:
466 {
467 objID = mesonConnectorGetCRTCId(s_conn_HDMI);
468 sprintf( propName, "%s", DRM_CONNECTOR_PROP_TX_HDR_POLICY);
469 objtype = DRM_MODE_OBJECT_CRTC;
470 break;
471 }
472 case ENUM_DRM_PROP_GETRX_HDCP_SUPPORTED_VERS:
473 {
474 objID = mesonConnectorGetId(s_conn_HDMI);
475 objtype = DRM_MODE_OBJECT_CONNECTOR;
476 sprintf( propName, "%s", DRM_CONNECTOR_PROP_RX_HDCP_SUPPORTED_VER);
477 break;
478 }
479 case ENUM_DRM_PROP_GETRX_HDR_CAP:
480 {
481 objID = mesonConnectorGetId(s_conn_HDMI);
482 objtype = DRM_MODE_OBJECT_CONNECTOR;
483 sprintf( propName, "%s", DRM_CONNECTOR_PROP_RX_HDR_CAP);
484 break;
485 }
486 case ENUM_DRM_PROP_GETTX_HDR_MODE:
487 {
488 objID = mesonConnectorGetId(s_conn_HDMI);
489 objtype = DRM_MODE_OBJECT_CONNECTOR;
490 sprintf( propName, "%s", DRM_CONNECTOR_PROP_TX_HDR_MODE);
491 break;
492 }
493 case ENUM_DRM_PROP_HDMI_ASPECT_RATIO:
494 {
495 objID = mesonConnectorGetId(s_conn_HDMI);
496 objtype = DRM_MODE_OBJECT_CONNECTOR;
497 sprintf( propName, "%s", DRM_CONNECTOR_PROP_TX_ASPECT_RATIO);
498 break;
499 }
limin.tianb3c16ad2022-06-22 14:28:27 +0800500 case ENUM_DRM_PROP_HDMI_DV_ENABLE:
501 {
502 objID = mesonConnectorGetCRTCId(s_conn_HDMI);
503 objtype = DRM_MODE_OBJECT_CRTC;
504 sprintf( propName, "%s", DRM_CONNECTOR_PROP_DV_ENABLE);
505 }
limin.tian75338482022-06-20 09:27:34 +0800506 default:
507 break;
508 }
509 struct mesonProperty* meson_prop = NULL;
510 meson_prop = mesonPropertyCreate(s_drm_fd, objID, objtype, propName);
511 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 {
523 objID = mesonConnectorGetId(s_conn_HDMI);
524 objtype = DRM_MODE_OBJECT_CONNECTOR;
525 sprintf( propName, "%s", DRM_CONNECTOR_PROP_RX_DV_CAP);
526 struct mesonProperty* meson_prop_dv = NULL;
527 meson_prop_dv = mesonPropertyCreate(s_drm_fd, objID, objtype, propName);
528 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 {
546 objID = mesonConnectorGetId(s_conn_HDMI);
547 objtype = DRM_MODE_OBJECT_CONNECTOR;
548 sprintf( propName, "%s", DRM_CONNECTOR_PROP_HDCP_PRIORITY);
549 struct mesonProperty* meson_prop_HDCP = NULL;
550 meson_prop_HDCP = mesonPropertyCreate(s_drm_fd, objID, objtype, propName);
551 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);
559 meson_drm_deinit();
560 ret = 0;
561out:
562 return ret;
563}
564
limin.tianb3c16ad2022-06-22 14:28:27 +0800565int meson_drm_open()
566{
567 int ret_fd = -1;
568 const char *card;
569 card= getenv("WESTEROS_DRM_CARD");
570 if ( !card ) {
571 card = DEFAULT_CARD;
572 }
573 ret_fd = open(card, O_RDONLY|O_CLOEXEC);
574 if ( ret_fd < 0 )
575 printf("\n drm card:%s open fail\n",card);
576 return ret_fd;
577}
578struct mesonConnector* get_current_connector(int drmFd)
579{
580 struct mesonConnector* connectorHDMI = NULL;
581 struct mesonConnector* connectorTV = NULL;
582 int HDMIconnected = 0;
583 connectorHDMI = mesonConnectorCreate(drmFd, DRM_MODE_CONNECTOR_HDMIA);
584 HDMIconnected = mesonConnectorGetConnectState(connectorHDMI);
585 if (HDMIconnected == 1) {
586 return connectorHDMI;
587 } else {
588 connectorTV = mesonConnectorCreate(drmFd, DRM_MODE_CONNECTOR_LVDS);
589 return connectorTV;
590 }
591}
limin.tian75338482022-06-20 09:27:34 +0800592
limin.tianb3c16ad2022-06-22 14:28:27 +0800593void meson_drm_close_fd(int drmFd)
594{
595 if (drmFd >= 0)
596 close(s_drm_fd);
597}
598
599int meson_drm_get_vblank_time(int drmFd, int nextVsync,uint64_t *vblankTime, uint64_t *refreshInterval)
600{
601 int ret = -1;
602 int rc = -1;
603 struct mesonConnector* connector = NULL;
604 drmModeModeInfo* mode = NULL;
605 if (drmFd < 0) {
606 printf("\n drmFd error\n");
607 goto out;
608 }
609 if (nextVsync < 0)
610 nextVsync = 0;
611 connector = get_current_connector(drmFd);
612 if (connector != NULL ) {
613 mode = mesonConnectorGetCurMode(drmFd, connector);
614 if (mode) {
615 *refreshInterval = (1000000LL+(mode->vrefresh/2))/mode->vrefresh;
616 free(mode);
617 ret = 0;
618 }
619 }
620 drmVBlank vbl;
621 vbl.request.type= DRM_VBLANK_RELATIVE;
622 vbl.request.sequence= nextVsync;
623 vbl.request.signal= 0;
624 rc = drmWaitVBlank(drmFd, &vbl );
625 if (rc != 0 ) {
626 printf("drmWaitVBlank failed: rc %d errno %d",rc, errno);
627 goto out;
628 }
629 if ((rc == 0) && (vbl.reply.tval_sec > 0 || vbl.reply.tval_usec > 0)) {
630 *vblankTime = vbl.reply.tval_sec * 1000000LL + vbl.reply.tval_usec;
631 }
632out:
633 mesonConnectorDestroy(drmFd, connector);
634 return ret;
635}
limin.tian75338482022-06-20 09:27:34 +0800636