libdrm-meson: implement libdrm-meson [1/1]
PD#SWPL-114279
Problem:
implement libdrm-meson for LGE
Solution:
add API:EDID/avmute/hdcp_auth status/enable hdcp
Verify:
ah212
Change-Id: I81ebdd02fe4ea6f4bc2797784740225588138d16
Signed-off-by: limin.tian <limin.tian@amlogic.com>
diff --git a/meson/meson_drm_settings.c b/meson/meson_drm_settings.c
index bd78a1c..6596cdf 100644
--- a/meson/meson_drm_settings.c
+++ b/meson/meson_drm_settings.c
@@ -39,13 +39,13 @@
struct mesonConnector* conn = NULL;
if ( drmFd < 0 || name == NULL || propValue == NULL)
{
- printf("\n%s %d drmfd invalid, or property name invalid\n",__FUNCTION__,__LINE__);
+ fprintf(stderr, "\n%s %d drmfd invalid, or property name invalid\n",__FUNCTION__,__LINE__);
goto out;
}
conn = get_current_connector(drmFd, connType);
if ( conn == NULL )
{
- printf("\n%s %d get_current_connector fail\n",__FUNCTION__,__LINE__);
+ fprintf(stderr, "\n%s %d get_current_connector fail\n",__FUNCTION__,__LINE__);
goto out;
}
objID = mesonConnectorGetId(conn);
@@ -59,7 +59,7 @@
}
uint64_t value = mesonPropertyGetValue(meson_prop);
*propValue = (uint32_t)value;
- printf("\n prop value:%llu objID:%d,name:%s\n",value, objID,name);
+ fprintf(stderr, "\n prop value:%llu objID:%d,name:%s\n",value, objID,name);
mesonPropertyDestroy(meson_prop);
ret = 0;
out:
@@ -83,7 +83,7 @@
struct mesonConnector* connector = NULL;
int drmConnType = DRM_MODE_CONNECTOR_HDMIA;
if (drmFd < 0) {
- printf("\n %s %d invalid drmFd return\n",__FUNCTION__,__LINE__);
+ fprintf(stderr, "\n %s %d invalid drmFd return\n",__FUNCTION__,__LINE__);
return NULL;
}
switch (connType)
@@ -117,15 +117,16 @@
}
ret_fd = open(card, O_RDONLY|O_CLOEXEC);
if ( ret_fd < 0 )
- printf("\n meson_open_drm drm card:%s open fail\n",card);
+ fprintf(stderr, "\n meson_open_drm drm card:%s open fail\n",card);
else
drmDropMaster(ret_fd);
ret = drmSetClientCap(ret_fd, DRM_CLIENT_CAP_ATOMIC, 1);
if (ret < 0)
- printf("Unable to set DRM atomic capability\n");
+ fprintf(stderr, "Unable to set DRM atomic capability\n");
+
ret = drmSetClientCap(ret_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
if (ret < 0)
- printf("Unable to set UNIVERSAL_PLANES\n");
+ fprintf(stderr, "Unable to set UNIVERSAL_PLANES\n");
return ret_fd;
}
void meson_close_drm(int drmFd)
@@ -139,17 +140,17 @@
uint32_t propId;
int rc = -1;
if (drmFd < 0 || req == NULL) {
- printf("\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
+ fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
return rc;
}
struct mesonProperty *prop = NULL;
prop = mesonPropertyCreate(drmFd, objId, objType, name);
propId = mesonPropertyGetId(prop);
mesonPropertyDestroy(prop);
- printf("\nmeson_drm_set_property name:%s propId:%d value:%llu\n", name, propId, value);
+ fprintf(stderr, "\nmeson_drm_set_property name:%s propId:%d value:%llu\n", name, propId, value);
rc = drmModeAtomicAddProperty( req, objId, propId, value );
if (rc < 0)
- printf("\n %s %d meson_drm_set_property fail\n",__FUNCTION__,__LINE__);
+ fprintf(stderr, "\n %s %d meson_drm_set_property fail\n",__FUNCTION__,__LINE__);
return rc;
}
@@ -159,7 +160,7 @@
struct mesonConnector* conn = NULL;
drmModeModeInfo* mode = NULL;
if (modeInfo == NULL || drmFd < 0) {
- printf("\n %s %d modeInfo == NULL || drmFd < 0 return\n",__FUNCTION__,__LINE__);
+ fprintf(stderr, "\n %s %d modeInfo == NULL || drmFd < 0 return\n",__FUNCTION__,__LINE__);
return ret;
}
conn = get_current_connector(drmFd, connType);
@@ -175,10 +176,10 @@
mode = NULL;
ret = 0;
} else {
- printf("\n %s %d mode get fail \n",__FUNCTION__,__LINE__);
+ fprintf(stderr, "\n %s %d mode get fail \n",__FUNCTION__,__LINE__);
}
} else {
- printf("\n %s %d conn create fail \n",__FUNCTION__,__LINE__);
+ fprintf(stderr, "\n %s %d conn create fail \n",__FUNCTION__,__LINE__);
}
if (conn)
mesonConnectorDestroy(drmFd,conn);
@@ -204,7 +205,7 @@
int modesNumber = 0;
if (modeInfo == NULL || drmFd < 0 || req == NULL) {
- printf("\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
+ fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
return ret;
}
conn = get_current_connector(drmFd, connType);
@@ -225,7 +226,7 @@
}
}
} else {
- printf("\n %s %d conn create fail \n",__FUNCTION__,__LINE__);
+ fprintf(stderr, "\n %s %d conn create fail \n",__FUNCTION__,__LINE__);
}
if (found) {
@@ -234,7 +235,7 @@
if (rc == 0) {
rc2 = meson_drm_set_property(drmFd, req, crtcId, DRM_MODE_OBJECT_CRTC, "MODE_ID", blobId);
rc3 = meson_drm_set_property(drmFd, req, crtcId, DRM_MODE_OBJECT_CRTC, "ACTIVE", 1);
- printf("\n %s %d rc1:%d rc:%d rc2:%d, rc3:%d\n",__FUNCTION__,__LINE__, rc1, rc,rc2,rc3);
+ fprintf(stderr, "\n %s %d rc1:%d rc:%d rc2:%d, rc3:%d\n",__FUNCTION__,__LINE__, rc1, rc,rc2,rc3);
if (rc1 >= 0 && rc2 >= 0 && rc3 >= 0)
ret = 0;
}
@@ -249,7 +250,7 @@
ENUM_MESON_CONN_CONNECTION ret = MESON_UNKNOWNCONNECTION;
struct mesonConnector* conn = NULL;
if ( drmFd < 0) {
- printf("\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
+ fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
return ret;
}
conn = get_current_connector(drmFd, connType);
@@ -264,7 +265,7 @@
ret = MESON_UNKNOWNCONNECTION;
}
} else {
- printf("\n drm open fail\n");
+ fprintf(stderr, "\n drm open fail\n");
}
if (conn)
mesonConnectorDestroy(drmFd,conn);
@@ -278,7 +279,7 @@
uint32_t value = 0;
ENUM_MESON_COLOR_SPACE colorSpace = MESON_COLOR_SPACE_RESERVED;
if ( drmFd < 0) {
- printf("\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
+ fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
return colorSpace;
}
if ( 0 == meson_drm_get_conn_prop_value(drmFd, connType, propName, &value )) {
@@ -301,7 +302,7 @@
break;
}
} else {
- printf("\n%s %d fail\n",__FUNCTION__,__LINE__);
+ fprintf(stderr, "\n%s %d fail\n",__FUNCTION__,__LINE__);
}
return colorSpace;
}
@@ -313,7 +314,7 @@
int rc = -1;
struct mesonConnector* conn = NULL;
if ( drmFd < 0 || req == NULL) {
- printf("\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
+ fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
return ret;
}
conn = get_current_connector(drmFd, connType);
@@ -335,11 +336,11 @@
sprintf( propName, "%s", DRM_CONNECTOR_PROP_COLOR_DEPTH);
uint32_t value = 0;
if ( drmFd < 0) {
- printf("\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
+ fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
return value;
}
if ( 0 != meson_drm_get_conn_prop_value( drmFd, connType, propName, &value )) {
- printf("\n%s %d fail\n",__FUNCTION__,__LINE__);
+ fprintf(stderr, "\n%s %d fail\n",__FUNCTION__,__LINE__);
}
return value;
}
@@ -352,7 +353,7 @@
uint32_t connId = 0;
conn = get_current_connector(drmFd, connType);
if ( drmFd < 0 || req == NULL) {
- printf("\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
+ fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
return ret;
}
if (conn) {
@@ -372,7 +373,7 @@
uint32_t value = 0;
ENUM_MESON_HDR_POLICY hdrPolicy = MESON_HDR_POLICY_FOLLOW_SINK;
if ( drmFd < 0) {
- printf("\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
+ fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
return hdrPolicy;
}
if ( 0 == meson_drm_get_crtc_prop_value( drmFd, connType, propName, &value )) {
@@ -393,7 +394,7 @@
uint32_t crtcId = 0;
conn = get_current_connector(drmFd, connType);
if ( drmFd < 0 || req == NULL) {
- printf("\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
+ fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
return ret;
}
if (conn) {
@@ -414,7 +415,7 @@
uint32_t value = 0;
ENUM_MESON_HDCP_VERSION hdcpVersion = MESON_HDCP_RESERVED;
if ( drmFd < 0) {
- printf("\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
+ fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
return hdcpVersion;
}
if ( 0 == meson_drm_get_conn_prop_value( drmFd, connType, propName, &value )) {
@@ -433,7 +434,7 @@
uint32_t value = 0;
ENUM_MESON_HDR_MODE hdrMode = MESON_SDR;
if ( drmFd < 0) {
- printf("\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
+ fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
return hdrMode;
}
if ( 0 == meson_drm_get_conn_prop_value( drmFd, connType, propName, &value )) {
@@ -465,8 +466,106 @@
break;
}
} else {
- printf("\n%s %d fail\n",__FUNCTION__,__LINE__);
+ fprintf(stderr, "\n%s %d fail\n",__FUNCTION__,__LINE__);
}
return hdrMode;
}
+void meson_drm_getEDIDData(int drmFd, MESON_CONNECTOR_TYPE connType, int * data_Len, char **data )
+{
+ int i = 0;
+ int count = 0;
+ char* edid_data = NULL;
+ struct mesonConnector* conn = NULL;
+ if (drmFd < 0 || data_Len == NULL || data == NULL) {
+ fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
+ return;
+ }
+ conn = get_current_connector(drmFd, connType);
+ if (conn == NULL) {
+ fprintf(stderr, "\n%s %d connector create fail.return \n",__FUNCTION__,__LINE__);
+ return;
+ }
+ if (0 != mesonConnectorGetEdidBlob(conn, &count, &edid_data))
+ goto out;
+ char* edid = (char*)calloc(count, sizeof(char));
+ if (edid == NULL) {
+ fprintf(stderr, "\n%s %d edid alloc mem fail.return\n",__FUNCTION__,__LINE__);
+ return;
+ }
+ for (i = 0; i < count; i++)
+ {
+ edid[i] = edid_data[i];
+ }
+ *data_Len = count;
+ *data = edid;
+out:
+ if (conn)
+ mesonConnectorDestroy(drmFd,conn);
+}
+
+int meson_drm_setAVMute(int drmFd, drmModeAtomicReq *req,
+ bool mute, MESON_CONNECTOR_TYPE connType)
+
+{
+ int ret = -1;
+ int rc = -1;
+ struct mesonConnector* conn = NULL;
+ uint32_t connId = 0;
+ if ( drmFd < 0 || req == NULL) {
+ fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
+ return ret;
+ }
+ conn = get_current_connector(drmFd, connType);
+ if (conn) {
+ connId = mesonConnectorGetId(conn);
+ rc = meson_drm_set_property(drmFd, req, connId, DRM_MODE_OBJECT_CONNECTOR,
+ MESON_DRM_HDMITX_PROP_AVMUTE, (uint64_t)mute);
+ mesonConnectorDestroy(drmFd,conn);
+ }
+ if (rc >= 0)
+ ret = 0;
+ return ret;
+}
+ENUM_MESON_HDCPAUTH_STATUS meson_drm_getHdcpAuthStatus( int drmFd, MESON_CONNECTOR_TYPE connType )
+{
+ char propName[PROP_NAME_MAX_LEN] = {'\0'};
+ sprintf( propName, "%s", DRM_CONNECTOR_PROP_CONTENT_PROTECTION);
+ uint32_t value = 0;
+ ENUM_MESON_HDCPAUTH_STATUS hdcpAuthStatus = MESON_AUTH_STATUS_FAIL;
+ if ( drmFd < 0 ) {
+ fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
+ return hdcpAuthStatus;
+ }
+ if ( 0 == meson_drm_get_conn_prop_value( drmFd, connType, propName, &value )) {
+ if (value == 2)
+ hdcpAuthStatus = MESON_AUTH_STATUS_SUCCESS;
+ }
+ return hdcpAuthStatus;
+}
+
+int meson_drm_setHDCPEnable(int drmFd, drmModeAtomicReq *req,
+ bool enable, MESON_CONNECTOR_TYPE connType)
+
+{
+ int ret = -1;
+ int rc = -1;
+ struct mesonConnector* conn = NULL;
+ uint32_t connId = 0;
+ if ( drmFd < 0 || req == NULL) {
+ fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
+ return ret;
+ }
+ conn = get_current_connector(drmFd, connType);
+ if (conn) {
+ connId = mesonConnectorGetId(conn);
+ rc = meson_drm_set_property(drmFd, req, connId, DRM_MODE_OBJECT_CONNECTOR,
+ DRM_CONNECTOR_PROP_CONTENT_PROTECTION, (uint64_t)enable);
+ mesonConnectorDestroy(drmFd,conn);
+ }
+ if (rc >= 0)
+ ret = 0;
+ return ret;
+}
+
+
diff --git a/meson/meson_drm_settings.h b/meson/meson_drm_settings.h
index dcf1b48..b7c4258 100644
--- a/meson/meson_drm_settings.h
+++ b/meson/meson_drm_settings.h
@@ -71,6 +71,11 @@
MESON_HDR_POLICY_FOLLOW_SOURCE
} ENUM_MESON_HDR_POLICY;
+typedef enum _ENUM_MESON_HDCP_AUTH_STATUS {
+ MESON_AUTH_STATUS_FAIL = 0,
+ MESON_AUTH_STATUS_SUCCESS
+} ENUM_MESON_HDCPAUTH_STATUS;
+
int meson_drm_changeMode(int drmFd, drmModeAtomicReq *req,
DisplayMode* modeInfo, MESON_CONNECTOR_TYPE connType);
int meson_drm_getModeInfo(int drmFd, MESON_CONNECTOR_TYPE connType, DisplayMode* mode );
@@ -90,6 +95,14 @@
int meson_drm_setHDRPolicy(int drmFd, drmModeAtomicReq *req,
ENUM_MESON_HDR_POLICY hdrPolicy, MESON_CONNECTOR_TYPE connType);
+
+void meson_drm_getEDIDData(int drmFd, MESON_CONNECTOR_TYPE connType, int * data_Len, char **data );
+int meson_drm_setAVMute(int drmFd, drmModeAtomicReq *req,
+ bool mute, MESON_CONNECTOR_TYPE connType);
+ENUM_MESON_HDCPAUTH_STATUS meson_drm_getHdcpAuthStatus( int drmFd, MESON_CONNECTOR_TYPE connType );
+int meson_drm_setHDCPEnable(int drmFd, drmModeAtomicReq *req,
+ bool enable, MESON_CONNECTOR_TYPE connType);
+
int meson_open_drm();
void meson_close_drm(int drmFd);
diff --git a/meson/meson_drm_settings_test.c b/meson/meson_drm_settings_test.c
index d0b3238..3b1fc08 100644
--- a/meson/meson_drm_settings_test.c
+++ b/meson/meson_drm_settings_test.c
@@ -10,43 +10,49 @@
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
+#include <errno.h>
#include <linux/string.h>
+#include "xf86drm.h"
+#include "xf86drmMode.h"
#include "libdrm_meson_connector.h"
#include "libdrm_meson_property.h"
#include "meson_drm_settings.h"
+#define DEFAULT_CARD "/dev/dri/card0"
int main(void )
{
printf("\n test meson_drm_settings test start\n");
int select_s_g = 0;
uint32_t value = 255;
+ int select_len = 0;
printf("\n 0->set prop 1->get\n");
- scanf("%d",&select_s_g);
- if (select_s_g == 1) {
- printf("get value:1.HDCP version 2.HDMI connected 3.color space 4. color depth 5. hdr mode 6. mode 7. hdr policy\n");
+ select_len = scanf("%d",&select_s_g);
+ if (select_s_g == 1 && select_len == 1) {
+ printf("get value: 1.HDCP version 2.HDMI connected 3.color space 4. color depth"
+ "5. hdr mode 6. mode 7. hdr policy 8. EDID 9. hdcp auth status\n");
int get = 0;
int drmFd = meson_open_drm();
int len = scanf("%d", &get);
- if (get == 1) {
+ if (get == 1 && len == 1) {
ENUM_MESON_HDCP_VERSION value = meson_drm_getHdcpVersion( drmFd,MESON_CONNECTOR_HDMIA );
printf("\n MESON_HDCP_14 = 0\n"
" MESON_HDCP_22 = 1\n value:%d \n", value);
- } else if (get == 2) {
+ } else if (get == 2 && len == 1) {
ENUM_MESON_CONN_CONNECTION value = meson_drm_getConnectionStatus(drmFd,MESON_CONNECTOR_HDMIA);
printf("\n MESON_DISCONNECTED = 0\n"
" MESON_CONNECTED = 1\n value:%d \n",value);
- } else if (get == 3) {
+ } else if (get == 3 && len == 1) {
ENUM_MESON_COLOR_SPACE value = meson_drm_getColorSpace( drmFd, MESON_CONNECTOR_HDMIA );
printf("\n MESON_COLOR_SPACE_RGB = 0 \n"
"MESON_COLOR_SPACE_YCBCR422 = 1 \n"
"MESON_COLOR_SPACE_YCBCR444 = 2 \n"
"MESON_COLOR_SPACE_YCBCR420 = 3 \n value:%d\n"
, value);
- } else if (get == 4) {
+ } else if (get == 4 && len == 1) {
uint32_t value = meson_drm_getColorDepth( drmFd, MESON_CONNECTOR_HDMIA );
- printf("\n color depth::%d\n",value);
+ printf("\n color depth:%d\n",value);
}
- else if (get == 5) {
+ else if (get == 5 && len == 1) {
ENUM_MESON_HDR_MODE value = meson_drm_getHdrStatus( drmFd, MESON_CONNECTOR_HDMIA );
printf("\n MESON_HDR10PLUS = 0 \n"
" MESON_DOLBYVISION_STD \n"
@@ -56,19 +62,81 @@
" MESON_HDR_HLG \n"
" MESON_SDR \n value:%d\n"
, value);
- } else if (get == 6) {
+ } else if (get == 6 && len == 1) {
DisplayMode mode;
if (meson_drm_getModeInfo(drmFd, MESON_CONNECTOR_HDMIA, &mode ) == 0) {
printf("\n mode (%d %d %d %d)\n",mode.w, mode.h, mode.vrefresh, mode.interlace);
}
- } else if (get == 7) {
+ } else if (get == 7 && len == 1) {
ENUM_MESON_HDR_POLICY value = meson_drm_getHDRPolicy(drmFd, MESON_CONNECTOR_HDMIA );
printf("\n MESON_HDR_POLICY_FOLLOW_SINK = 0 \n"
"MESON_HDR_POLICY_FOLLOW_SOURCE = 1 \n value:%d\n", value);
+ } else if (get == 8 && len == 1) {
+ int len = 0;
+ char *edid = NULL;
+ int i;
+ meson_drm_getEDIDData(drmFd, MESON_CONNECTOR_HDMIA, &len, &edid );
+ printf("\n EDID data len:%d\n", len);
+ for (i = 0; i < len; i++) {
+ if (i % 16 == 0)
+ printf("\n\t\t\t");
+ if (edid)
+ printf("%.2hhx", edid[i]);
+ }
+ printf("\n");
+ if (edid)
+ free(edid);
+ } else if (get == 9 && len == 1) {
+ ENUM_MESON_HDCPAUTH_STATUS value = MESON_AUTH_STATUS_FAIL;
+ value = meson_drm_getHdcpAuthStatus( drmFd, MESON_CONNECTOR_HDMIA );
+ printf("\n MESON_AUTH_STATUS_FAIL = 0 \n"
+ " MESON_AUTH_STATUS_SUCCESS = 1 \n value:%d\n", value);
}
meson_close_drm(drmFd);
- } else if (select_s_g == 0) {
- printf("\n set prop test not implement\n");
+ } else if (select_s_g == 0 && select_len == 1) {
+ printf("set value:1.av mute 2.HDMI HDCP enable \n");
+ int set = 0;
+ int ret = -1;
+ drmModeAtomicReq * req;
+ int drmFd = open(DEFAULT_CARD, O_RDWR|O_CLOEXEC);
+ if (drmFd < 0) {
+ fprintf(stderr, "failed to open device %s\n", strerror(errno));
+ }
+ /*use atomic*/
+ ret = drmSetClientCap(drmFd, DRM_CLIENT_CAP_ATOMIC, 1);
+ if (ret) {
+ fprintf(stderr, "no atomic modesetting support: %s\n", strerror(errno));
+ drmClose(drmFd);
+ }
+ req = drmModeAtomicAlloc();
+ int len = scanf("%d", &set);
+ if (set == 1 && len == 1) {
+ printf("\n av mute:\n");
+ int avmute = 0;
+ len = scanf("%d", &avmute);
+ if (len == 1) {
+ if (meson_drm_setAVMute(drmFd, req, avmute, MESON_CONNECTOR_HDMIA))
+ printf("\n meson_drm_setAVMute fail:\n");
+ } else {
+ printf("\n scanf fail\n");
+ }
+ } else if (set == 2 && len == 1) {
+ printf("\n HDCP enable:\n");
+ int hdcpEnable = 0;
+ len = scanf("%d", &hdcpEnable);
+ if (len == 1) {
+ if (meson_drm_setHDCPEnable( drmFd, req, hdcpEnable, MESON_CONNECTOR_HDMIA))
+ printf("\n meson_drm_setAVMute fail:\n");
+ } else {
+ printf("\n scanf fail\n");
+ }
+ }
+ ret = drmModeAtomicCommit(drmFd, req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+ if (ret) {
+ fprintf(stderr, "failed to set mode: %d-%s\n", ret, strerror(errno));
+ }
+ drmModeAtomicFree(req);
+ drmClose(drmFd);
}
getchar();
exit: