blob: 08b54a78397a78320dd0560dbd84dcae9890a2c0 [file] [log] [blame]
/*
* Copyright (c) 2023 Amlogic, Inc. All rights reserved.
*
* This source code is subject to the terms and conditions defined in the
* file 'LICENSE' which is part of this source code package.
*
* Description:
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#include <linux/string.h>
#include "libdrm_meson_connector.h"
#include "libdrm_meson_property.h"
#include "meson_drm_settings.h"
#define DEFAULT_CARD "/dev/dri/card0"
#define PROP_NAME_MAX_LEN 50
static int meson_drm_get_crtc_prop_value( int drmFd, MESON_CONNECTOR_TYPE connType,
char* name, uint32_t* prop_value );
static int meson_drm_get_conn_prop_value( int drmFd, MESON_CONNECTOR_TYPE connType,
char* name, uint32_t* propValue );
static int meson_drm_get_prop_value(int drmFd, MESON_CONNECTOR_TYPE connType,
uint32_t objType, char* name, uint32_t* propValue );
static struct mesonConnector* get_current_connector(int drmFd, MESON_CONNECTOR_TYPE connType);
static int meson_drm_set_property(int drmFd, drmModeAtomicReq *req, uint32_t objId,
uint32_t objType, char* name, uint64_t value);
static int meson_drm_get_prop_value(int drmFd, MESON_CONNECTOR_TYPE connType, uint32_t objType, char* name, uint32_t* propValue )
{
int ret = -1;
int objID = -1;
struct mesonConnector* conn = NULL;
if ( drmFd < 0 || name == NULL || propValue == NULL)
{
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 )
{
fprintf(stderr, "\n%s %d get_current_connector fail\n",__FUNCTION__,__LINE__);
goto out;
}
objID = mesonConnectorGetId(conn);
if (objType == DRM_MODE_OBJECT_CRTC)
objID = mesonConnectorGetCRTCId(conn);
struct mesonProperty* meson_prop = NULL;
meson_prop = mesonPropertyCreate(drmFd, objID, objType, name);
if (!meson_prop) {
printf("\n meson_prop create fail\n");
goto out;
}
uint64_t value = mesonPropertyGetValue(meson_prop);
*propValue = (uint32_t)value;
fprintf(stderr, "\n prop value:%llu objID:%d,name:%s\n",value, objID,name);
mesonPropertyDestroy(meson_prop);
ret = 0;
out:
if (conn)
mesonConnectorDestroy(drmFd,conn);
return ret;
}
static int meson_drm_get_conn_prop_value( int drmFd, MESON_CONNECTOR_TYPE conn_type, char* name, uint32_t* prop_value )
{
return meson_drm_get_prop_value( drmFd, conn_type, DRM_MODE_OBJECT_CONNECTOR, name, prop_value );
}
static int meson_drm_get_crtc_prop_value( int drmFd, MESON_CONNECTOR_TYPE conn_type, char* name, uint32_t* prop_value )
{
return meson_drm_get_prop_value( drmFd, conn_type, DRM_MODE_OBJECT_CRTC, name, prop_value );
}
static struct mesonConnector* get_current_connector(int drmFd, MESON_CONNECTOR_TYPE connType)
{
struct mesonConnector* connector = NULL;
int drmConnType = DRM_MODE_CONNECTOR_HDMIA;
if (drmFd < 0) {
fprintf(stderr, "\n %s %d invalid drmFd return\n",__FUNCTION__,__LINE__);
return NULL;
}
switch (connType)
{
case MESON_CONNECTOR_HDMIA:
drmConnType = DRM_MODE_CONNECTOR_HDMIA;
break;
case MESON_CONNECTOR_HDMIB:
drmConnType = DRM_MODE_CONNECTOR_HDMIB;
break;
case MESON_CONNECTOR_LVDS:
drmConnType = DRM_MODE_CONNECTOR_LVDS;
break;
case MESON_CONNECTOR_CVBS:
drmConnType = DRM_MODE_CONNECTOR_TV;
break;
default :
drmConnType = DRM_MODE_CONNECTOR_HDMIA;
break;
}
connector = mesonConnectorCreate(drmFd, drmConnType);
return connector;
}
int meson_open_drm()
{
int ret_fd = -1;
const char *card;
int ret = -1;
card= getenv("WESTEROS_DRM_CARD");
if ( !card ) {
card = DEFAULT_CARD;
}
ret_fd = open(card, O_RDONLY|O_CLOEXEC);
if ( ret_fd < 0 )
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)
fprintf(stderr, "Unable to set DRM atomic capability\n");
ret = drmSetClientCap(ret_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
if (ret < 0)
fprintf(stderr, "Unable to set UNIVERSAL_PLANES\n");
return ret_fd;
}
void meson_close_drm(int drmFd)
{
if (drmFd >= 0)
close(drmFd);
}
static int meson_drm_set_property(int drmFd, drmModeAtomicReq *req, uint32_t objId,
uint32_t objType, char* name, uint64_t value)
{
uint32_t propId;
int rc = -1;
if (drmFd < 0 || req == NULL) {
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);
fprintf(stderr, "\nmeson_drm_set_property name:%s objId:%d propId:%d value:%llu\n", name, objId, propId, value);
rc = drmModeAtomicAddProperty( req, objId, propId, value );
if (rc < 0)
fprintf(stderr, "\n %s %d meson_drm_set_property fail\n",__FUNCTION__,__LINE__);
return rc;
}
int meson_drm_getPreferredMode( DisplayMode* mode) {
int ret = -1;
int i = 0;
int count = 0;
drmModeModeInfo* modes = NULL;
int drmFd = -1;
struct mesonConnector* conn = NULL;
drmFd = meson_open_drm();
conn = mesonConnectorCreate(drmFd, DRM_MODE_CONNECTOR_HDMIA);
if (conn == NULL || drmFd < 0)
{
printf("\n%s %d connector create fail\n",__FUNCTION__,__LINE__);
}
if (0 != mesonConnectorGetModes(conn, drmFd, &modes, &count))
goto out;
for (i = 0; i < count; i++)
{
if (modes[i].type & DRM_MODE_TYPE_PREFERRED)
{
mode->w = modes[i].hdisplay;
mode->h = modes[i].vdisplay;
mode->interlace = (modes[i].flags & DRM_MODE_FLAG_INTERLACE) ? true : false;
strcpy(mode->name, modes[i].name );
break;
}
}
ret = 0;
out:
if (conn)
mesonConnectorDestroy(drmFd,conn);
if (drmFd >= 0 )
close(drmFd);
return ret;
}
int meson_drm_getsupportedModesList(int drmFd, DisplayMode** modeInfo, int* modeCount )
{
int ret = -1;
struct mesonConnector* conn = NULL;
if ( drmFd < 0) {
fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
return ret;
}
conn = mesonConnectorCreate(drmFd, DRM_MODE_CONNECTOR_HDMIA);
if (conn == NULL || drmFd < 0)
{
printf("\n%s %d connector create fail\n",__FUNCTION__,__LINE__);
}
drmModeModeInfo* modeall = NULL;
int count = 0;
int i = 0;
if (0 != mesonConnectorGetModes(conn, drmFd, &modeall, &count))
goto out;
DisplayMode* modestemp = (DisplayMode*)calloc(count, sizeof(DisplayMode));
for (i = 0; i < count; i++)
{
modestemp[i].w = modeall[i].hdisplay;
modestemp[i].h = modeall[i].vdisplay;
modestemp[i].vrefresh = modeall[i].vrefresh;
modestemp[i].interlace = (modeall[i].flags & DRM_MODE_FLAG_INTERLACE) ? true : false;
strcpy(modestemp[i].name, modeall[i].name );
}
*modeCount = count;
*modeInfo = modestemp;
ret = 0;
out:
if (conn)
mesonConnectorDestroy(drmFd,conn);
return ret;
}
int meson_drm_getModeInfo(int drmFd, MESON_CONNECTOR_TYPE connType, DisplayMode* modeInfo)
{
int ret = -1;
struct mesonConnector* conn = NULL;
drmModeModeInfo* mode = NULL;
if (modeInfo == NULL || drmFd < 0) {
fprintf(stderr, "\n %s %d modeInfo == NULL || drmFd < 0 return\n",__FUNCTION__,__LINE__);
return ret;
}
conn = get_current_connector(drmFd, connType);
if ( conn ) {
mode = mesonConnectorGetCurMode(drmFd, conn);
if (mode) {
modeInfo->w = mode->hdisplay;
modeInfo->h = mode->vdisplay;
modeInfo->vrefresh = mode->vrefresh;
modeInfo->interlace = mode->flags & DRM_MODE_FLAG_INTERLACE;
strcpy(modeInfo->name, mode->name);
free(mode);
mode = NULL;
ret = 0;
} else {
fprintf(stderr, "\n %s %d mode get fail \n",__FUNCTION__,__LINE__);
}
} else {
fprintf(stderr, "\n %s %d conn create fail \n",__FUNCTION__,__LINE__);
}
if (conn)
mesonConnectorDestroy(drmFd,conn);
return ret;
}
int meson_drm_changeMode(int drmFd, drmModeAtomicReq *req, DisplayMode* modeInfo, MESON_CONNECTOR_TYPE connType)
{
int ret = -1;
struct mesonConnector* conn = NULL;
drmModeModeInfo drm_mode;
int i;
bool interlace = false;
bool found = false;
int rc = -1;
int rc1 = -1;
int rc2 = -1;
int rc3 = -1;
uint32_t connId;
uint32_t crtcId;
uint32_t blobId = 0;
drmModeModeInfo* modes = NULL;
int modesNumber = 0;
if (modeInfo == NULL || drmFd < 0 || req == NULL) {
fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
return ret;
}
if (connType == MESON_CONNECTOR_CVBS)
{
struct mesonConnector* connHDMI = NULL;
uint32_t HDMIconnId;
int rc4 = -1;
connHDMI = get_current_connector(drmFd, MESON_CONNECTOR_HDMIA);
HDMIconnId = mesonConnectorGetId(connHDMI);
rc4 = meson_drm_set_property(drmFd, req, HDMIconnId, DRM_MODE_OBJECT_CONNECTOR, "CRTC_ID", 0);
mesonConnectorDestroy(drmFd,connHDMI);
fprintf(stderr, "\n %s %d change mode to cvbs, disconnect HDMI :%d \n",__FUNCTION__,__LINE__,rc4);
}
conn = get_current_connector(drmFd, connType);
connId = mesonConnectorGetId(conn);
crtcId = mesonConnectorGetCRTCId(conn);
if ( conn ) {
mesonConnectorGetModes(conn, drmFd, &modes, &modesNumber);
for ( i = 0; i < modesNumber; i++ ) {
interlace = (modes[i].flags & DRM_MODE_FLAG_INTERLACE);
if ( (modeInfo->w == modes[i].hdisplay)
&& (modeInfo->h == modes[i].vdisplay)
&& (modeInfo->vrefresh == modes[i].vrefresh)
&& (interlace == modeInfo->interlace)
) {
drm_mode = modes[i];
found = true;
break;
}
}
} else {
fprintf(stderr, "\n %s %d conn create fail \n",__FUNCTION__,__LINE__);
}
if (found) {
rc1 = meson_drm_set_property(drmFd, req, connId, DRM_MODE_OBJECT_CONNECTOR, "CRTC_ID", crtcId);
rc = drmModeCreatePropertyBlob( drmFd, &drm_mode, sizeof(drm_mode), &blobId );
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);
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;
}
}
if (conn)
mesonConnectorDestroy(drmFd,conn);
return ret;
}
ENUM_MESON_CONN_CONNECTION meson_drm_getConnectionStatus(int drmFd, MESON_CONNECTOR_TYPE connType)
{
ENUM_MESON_CONN_CONNECTION ret = MESON_UNKNOWNCONNECTION;
struct mesonConnector* conn = NULL;
if ( drmFd < 0) {
fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
return ret;
}
conn = get_current_connector(drmFd, connType);
if (conn) {
int ConnectState = -1;
ConnectState = mesonConnectorGetConnectState(conn);
if (ConnectState == 1) {
ret = MESON_CONNECTED;
} else if (ConnectState == 2) {
ret = MESON_DISCONNECTED;
} else {
ret = MESON_UNKNOWNCONNECTION;
}
} else {
fprintf(stderr, "\n drm open fail\n");
}
if (conn)
mesonConnectorDestroy(drmFd,conn);
return ret;
}
ENUM_MESON_COLOR_SPACE meson_drm_getColorSpace(int drmFd, MESON_CONNECTOR_TYPE connType )
{
char propName[PROP_NAME_MAX_LEN] = {'\0'};
sprintf( propName, "%s", DRM_CONNECTOR_PROP_COLOR_SPACE);
uint32_t value = 0;
ENUM_MESON_COLOR_SPACE colorSpace = MESON_COLOR_SPACE_RESERVED;
if ( drmFd < 0) {
fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
return colorSpace;
}
if ( 0 == meson_drm_get_conn_prop_value(drmFd, connType, propName, &value )) {
switch (value)
{
case 0:
colorSpace = MESON_COLOR_SPACE_RGB;
break;
case 1:
colorSpace = MESON_COLOR_SPACE_YCBCR422;
break;
case 2:
colorSpace = MESON_COLOR_SPACE_YCBCR444;
break;
case 3:
colorSpace = MESON_COLOR_SPACE_YCBCR420;
break;
default:
colorSpace = MESON_COLOR_SPACE_RESERVED;
break;
}
} else {
fprintf(stderr, "\n%s %d fail\n",__FUNCTION__,__LINE__);
}
return colorSpace;
}
int meson_drm_setColorSpace(int drmFd, drmModeAtomicReq *req,
ENUM_MESON_COLOR_SPACE colorSpace, MESON_CONNECTOR_TYPE connType)
{
int ret = -1;
uint32_t connId = 0;
int rc = -1;
struct mesonConnector* conn = NULL;
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_COLOR_SPACE, (uint64_t)colorSpace);
mesonConnectorDestroy(drmFd,conn);
}
if (rc >= 0)
ret = 0;
return ret;
}
uint32_t meson_drm_getColorDepth( int drmFd, MESON_CONNECTOR_TYPE connType )
{
char propName[PROP_NAME_MAX_LEN] = {'\0'};
sprintf( propName, "%s", DRM_CONNECTOR_PROP_COLOR_DEPTH);
uint32_t value = 0;
if ( drmFd < 0) {
fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
return value;
}
if ( 0 != meson_drm_get_conn_prop_value( drmFd, connType, propName, &value )) {
fprintf(stderr, "\n%s %d fail\n",__FUNCTION__,__LINE__);
}
return value;
}
int meson_drm_setColorDepth(int drmFd, drmModeAtomicReq *req,
uint32_t colorDepth, MESON_CONNECTOR_TYPE connType)
{
int ret = -1;
int rc = -1;
struct mesonConnector* conn = NULL;
uint32_t connId = 0;
conn = get_current_connector(drmFd, connType);
if ( drmFd < 0 || req == NULL) {
fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
return ret;
}
if (conn) {
connId = mesonConnectorGetId(conn);
rc = meson_drm_set_property(drmFd, req, connId, DRM_MODE_OBJECT_CONNECTOR,
DRM_CONNECTOR_PROP_COLOR_DEPTH, (uint64_t)colorDepth);
mesonConnectorDestroy(drmFd,conn);
}
if (rc >= 0)
ret = 0;
return ret;
}
ENUM_MESON_HDR_POLICY meson_drm_getHDRPolicy( int drmFd, MESON_CONNECTOR_TYPE connType )
{
char propName[PROP_NAME_MAX_LEN] = {'\0'};
sprintf( propName, "%s", DRM_CONNECTOR_PROP_TX_HDR_POLICY);
uint32_t value = 0;
ENUM_MESON_HDR_POLICY hdrPolicy = MESON_HDR_POLICY_FOLLOW_SINK;
if ( drmFd < 0) {
fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
return hdrPolicy;
}
if ( 0 == meson_drm_get_crtc_prop_value( drmFd, connType, propName, &value )) {
if (value == 0)
hdrPolicy = MESON_HDR_POLICY_FOLLOW_SINK;
if (value == 1)
hdrPolicy = MESON_HDR_POLICY_FOLLOW_SOURCE;
}
return hdrPolicy;
}
int meson_drm_setHDRPolicy(int drmFd, drmModeAtomicReq *req,
ENUM_MESON_HDR_POLICY hdrPolicy, MESON_CONNECTOR_TYPE connType)
{
int ret = -1;
int rc = -1;
struct mesonConnector* conn = NULL;
uint32_t crtcId = 0;
conn = get_current_connector(drmFd, connType);
if ( drmFd < 0 || req == NULL) {
fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
return ret;
}
if (conn) {
crtcId = mesonConnectorGetCRTCId(conn);
rc = meson_drm_set_property(drmFd, req, crtcId, DRM_MODE_OBJECT_CRTC,
DRM_CONNECTOR_PROP_TX_HDR_POLICY, (uint64_t)hdrPolicy);
mesonConnectorDestroy(drmFd,conn);
}
if (rc >= 0)
ret = 0;
return ret;
}
ENUM_MESON_HDCP_VERSION meson_drm_getHdcpVersion( int drmFd, MESON_CONNECTOR_TYPE connType )
{
char propName[PROP_NAME_MAX_LEN] = {'\0'};
sprintf( propName, "%s", DRM_CONNECTOR_PROP_TX_HDCP_AUTH_MODE);
uint32_t value = 0;
ENUM_MESON_HDCP_VERSION hdcpVersion = MESON_HDCP_RESERVED;
if ( drmFd < 0) {
fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
return hdcpVersion;
}
if ( 0 == meson_drm_get_conn_prop_value( drmFd, connType, propName, &value )) {
if (value & 0x1)
hdcpVersion = MESON_HDCP_14;
if (value & 0x2)
hdcpVersion = MESON_HDCP_22;
}
return hdcpVersion;
}
ENUM_MESON_HDR_MODE meson_drm_getHdrStatus(int drmFd, MESON_CONNECTOR_TYPE connType )
{
char propName[PROP_NAME_MAX_LEN] = {'\0'};
sprintf( propName, "%s", DRM_CONNECTOR_PROP_TX_HDR_MODE);
uint32_t value = 0;
ENUM_MESON_HDR_MODE hdrMode = MESON_SDR;
if ( drmFd < 0) {
fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
return hdrMode;
}
if ( 0 == meson_drm_get_conn_prop_value( drmFd, connType, propName, &value )) {
switch (value)
{
case 0:
hdrMode = MESON_HDR10PLUS;
break;
case 1:
hdrMode = MESON_DOLBYVISION_STD;
break;
case 2:
hdrMode = MESON_DOLBYVISION_LL;
break;
case 3:
hdrMode = MESON_HDR10_ST2084;
break;
case 4:
hdrMode = MESON_HDR10_TRADITIONAL;
break;
case 5:
hdrMode = MESON_HDR_HLG;
break;
case 6:
hdrMode = MESON_SDR;
break;
default:
hdrMode = MESON_SDR;
break;
}
} else {
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;
}
int meson_drm_getAVMute( int drmFd, MESON_CONNECTOR_TYPE connType )
{
char propName[PROP_NAME_MAX_LEN] = {'\0'};
sprintf( propName, "%s", MESON_DRM_HDMITX_PROP_AVMUTE);
uint32_t value = 0;
if ( drmFd < 0) {
fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
return value;
}
if ( 0 != meson_drm_get_conn_prop_value( drmFd, connType, propName, &value )) {
fprintf(stderr, "\n%s %d fail\n",__FUNCTION__,__LINE__);
}
fprintf(stderr, "\n AVMute control, 1 means set avmute, 0 means not avmute\n");
return value;
}
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;
}
int meson_drm_setHDCPContentType(int drmFd, drmModeAtomicReq *req,
ENUM_MESON_HDCP_Content_Type HDCPType, 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_TYPE, (uint64_t)HDCPType);
mesonConnectorDestroy(drmFd,conn);
}
if (rc >= 0)
ret = 0;
return ret;
}
ENUM_MESON_HDCP_Content_Type meson_drm_getHDCPContentType( int drmFd, MESON_CONNECTOR_TYPE connType )
{
char propName[PROP_NAME_MAX_LEN] = {'\0'};
sprintf( propName, "%s", DRM_CONNECTOR_PROP_CONTENT_TYPE);
uint32_t value = 0;
ENUM_MESON_HDCP_Content_Type ContentType = MESON_HDCP_Type_RESERVED;
if ( drmFd < 0) {
fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
return ContentType;
}
if ( 0 == meson_drm_get_conn_prop_value( drmFd, connType, propName, &value )) {
switch (value)
{
case 0:
ContentType = MESON_HDCP_Type0;
break;
case 1:
ContentType = MESON_HDCP_Type1;
break;
default:
ContentType = MESON_HDCP_Type_RESERVED;
break;
}
} else {
fprintf(stderr, "\n%s %d fail\n",__FUNCTION__,__LINE__);
}
return ContentType;
}
MESON_CONTENT_TYPE meson_drm_getContentType(int drmFd, MESON_CONNECTOR_TYPE connType ) {
char propName[PROP_NAME_MAX_LEN] = {'\0'};
sprintf( propName, "%s", DRM_CONNECTOR_PROP_Content_Type);
uint32_t value = 0;
MESON_CONTENT_TYPE ContentType = MESON_CONTENT_TYPE_RESERVED;
if ( drmFd < 0) {
fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
return ContentType;
}
if ( 0 == meson_drm_get_conn_prop_value(drmFd, connType, propName, &value )) {
switch (value)
{
case 0:
ContentType = MESON_CONTENT_TYPE_Data;
break;
case 1:
ContentType = MESON_CONTENT_TYPE_Graphics;
break;
case 2:
ContentType = MESON_CONTENT_TYPE_Photo;
break;
case 3:
ContentType = MESON_CONTENT_TYPE_Cinema;
break;
case 4:
ContentType = MESON_CONTENT_TYPE_Game;
break;
default:
ContentType = MESON_CONTENT_TYPE_RESERVED;
break;
}
} else {
fprintf(stderr, "\n%s %d fail\n",__FUNCTION__,__LINE__);
}
return ContentType;
}
int meson_drm_setDvEnable(int drmFd, drmModeAtomicReq *req,
uint32_t dvEnable, MESON_CONNECTOR_TYPE connType)
{
int ret = -1;
int rc = -1;
struct mesonConnector* conn = NULL;
uint32_t crtcId = 0;
conn = get_current_connector(drmFd, connType);
if ( drmFd < 0 || req == NULL) {
fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
return ret;
}
if (conn) {
crtcId = mesonConnectorGetCRTCId(conn);
rc = meson_drm_set_property(drmFd, req, crtcId, DRM_MODE_OBJECT_CRTC,
DRM_CONNECTOR_PROP_DV_ENABLE, (uint64_t)dvEnable);
mesonConnectorDestroy(drmFd,conn);
}
if (rc >= 0)
ret = 0;
return ret;
}
int meson_drm_getDvEnable( int drmFd, MESON_CONNECTOR_TYPE connType )
{
char propName[PROP_NAME_MAX_LEN] = {'\0'};
sprintf( propName, "%s", DRM_CONNECTOR_PROP_DV_ENABLE);
uint32_t value = -1;
if ( drmFd < 0) {
fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
return value;
}
if ( 0 != meson_drm_get_crtc_prop_value( drmFd, connType, propName, &value )) {
fprintf(stderr, "\n%s %d fail\n",__FUNCTION__,__LINE__);
}
return value;
}
int meson_drm_setActive(int drmFd, drmModeAtomicReq *req,
uint32_t active, MESON_CONNECTOR_TYPE connType)
{
int ret = -1;
int rc = -1;
struct mesonConnector* conn = NULL;
uint32_t crtcId = 0;
conn = get_current_connector(drmFd, connType);
if ( drmFd < 0 || req == NULL) {
fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
return ret;
}
if (conn) {
crtcId = mesonConnectorGetCRTCId(conn);
rc = meson_drm_set_property(drmFd, req, crtcId, DRM_MODE_OBJECT_CRTC,
DRM_CONNECTOR_PROP_ACTIVE, (uint64_t)active);
mesonConnectorDestroy(drmFd,conn);
}
if (rc >= 0)
ret = 0;
return ret;
}
int meson_drm_getActive( int drmFd, MESON_CONNECTOR_TYPE connType )
{
char propName[PROP_NAME_MAX_LEN] = {'\0'};
sprintf( propName, "%s", DRM_CONNECTOR_PROP_ACTIVE);
uint32_t value = 0;
if ( drmFd < 0) {
fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
return value;
}
if ( 0 != meson_drm_get_crtc_prop_value( drmFd, connType, propName, &value )) {
fprintf(stderr, "\n%s %d fail\n",__FUNCTION__,__LINE__);
}
return value;
}
int meson_drm_setVrrEnabled(int drmFd, drmModeAtomicReq *req,
uint32_t VrrEnable, MESON_CONNECTOR_TYPE connType)
{
int ret = -1;
int rc = -1;
struct mesonConnector* conn = NULL;
uint32_t crtcId = 0;
conn = get_current_connector(drmFd, connType);
if ( drmFd < 0 || req == NULL) {
fprintf(stderr, "\n %s %d invalid parameter return\n",__FUNCTION__,__LINE__);
return ret;
}
if (conn) {
crtcId = mesonConnectorGetCRTCId(conn);
rc = meson_drm_set_property(drmFd, req, crtcId, DRM_MODE_OBJECT_CRTC,
DRM_CONNECTOR_VRR_ENABLED, (uint64_t)VrrEnable);
mesonConnectorDestroy(drmFd,conn);
}
if (rc >= 0)
ret = 0;
return ret;
}
int meson_drm_getVrrEnabled( int drmFd, MESON_CONNECTOR_TYPE connType )
{
char propName[PROP_NAME_MAX_LEN] = {'\0'};
sprintf( propName, "%s", DRM_CONNECTOR_VRR_ENABLED);
uint32_t value = 0;
if ( drmFd < 0) {
fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
return value;
}
if ( 0 != meson_drm_get_crtc_prop_value( drmFd, connType, propName, &value )) {
fprintf(stderr, "\n%s %d fail\n",__FUNCTION__,__LINE__);
}
return value;
}
int meson_drm_getHdrCap( int drmFd, MESON_CONNECTOR_TYPE connType )
{
char propName[PROP_NAME_MAX_LEN] = {'\0'};
sprintf( propName, "%s", DRM_CONNECTOR_PROP_RX_HDR_CAP);
uint32_t value = 0;
if ( drmFd < 0) {
fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
return value;
}
if ( 0 != meson_drm_get_conn_prop_value( drmFd, connType, propName, &value )) {
fprintf(stderr, "\n%s %d fail\n",__FUNCTION__,__LINE__);
}
fprintf(stderr, "hdr_cap:presents the RX HDR capability [r]\n");
return value;
}
int meson_drm_getDvCap( int drmFd, MESON_CONNECTOR_TYPE connType )
{
char propName[PROP_NAME_MAX_LEN] = {'\0'};
sprintf( propName, "%s", DRM_CONNECTOR_PROP_RX_DV_CAP);
uint32_t value = 0;
if ( drmFd < 0) {
fprintf(stderr, "\n%s %d drmFd < 0\n",__FUNCTION__,__LINE__);
return value;
}
if ( 0 != meson_drm_get_conn_prop_value( drmFd, connType, propName, &value )) {
fprintf(stderr, "\n%s %d fail\n",__FUNCTION__,__LINE__);
}
fprintf(stderr, "dv_cap:presents the RX dolbyvision capability, [r] such as std or ll mode \n");
return value;
}