HDMI Framework develop

Signed-off-by: lzl <sucer_fater@163.com>
This commit is contained in:
lzl
2021-10-14 11:43:47 +00:00
parent de31d73bca
commit c83a8a6519
30 changed files with 14471 additions and 0 deletions
+745
View File
@@ -0,0 +1,745 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
/**
* @addtogroup HDMI
* @{
*
* @brief Declares standard APIs of basic High-Definition Multimedia Interface (HDMI) capabilities.
*
* You can use this module to access the HDMI and enable the driver to operate an HDMI sink device.
* These capabilities include start and stop tramnsfer on HDMI, setting some attributes,
* and read sink device's EDID data.
*
* @since 1.0
*/
/**
* @file hdmi_if.h
*
* @brief Declares the standard HDMI interface functions.
*
* @since 1.0
*/
#ifndef HDMI_IF_H
#define HDMI_IF_H
#include "hdf_platform.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
/**
* @brief Indicates that maximum length of an HDMI sink device's EDID is 512 bytes.
*
* @since 1.0
*/
#define HDMI_EDID_MAX_LEN 512
/**
* @brief Enumerates deep color,
* see the section 6.2.4 of HDMI Specification 1.4 for details.
*
* @since 1.0
*/
enum HdmiDeepColor {
HDMI_DEEP_COLOR_24BITS = 0,
HDMI_DEEP_COLOR_30BITS = 1,
HDMI_DEEP_COLOR_36BITS = 2,
HDMI_DEEP_COLOR_48BITS = 3,
HDMI_DEEP_COLOR_OFF = 0xff,
HDMI_DEEP_COLOR_BUTT,
};
/**
* @brief Enumerates video bit depth
* see the section 6.6 of HDMI Specification 1.4 for details.
*
* @since 1.0
*/
enum HdmiVideoBitDepth {
HDMI_VIDEO_BIT_DEPTH_8 = 0,
HDMI_VIDEO_BIT_DEPTH_10 = 1,
HDMI_VIDEO_BIT_DEPTH_12 = 2,
HDMI_VIDEO_BIT_DEPTH_16 = 3,
HDMI_VIDEO_BIT_DEPTH_OFF,
};
/**
* @brief Enumerates color space,
* see the section 6 of HDMI Specification 1.4 for details.
*
* @since 1.0
*/
enum HdmiColorSpace {
HDMI_COLOR_SPACE_RGB = 0,
HDMI_COLOR_SPACE_YCBCR422 = 1,
HDMI_COLOR_SPACE_YCBCR444 = 2,
HDMI_COLOR_SPACE_YCBCR420 = 3,
HDMI_COLOR_SPACE_BUTT,
};
/**
* @brief Enumerates colorimetry, see the section 6.7 of HDMI Specification 1.4 and
* the section 7.2 of HDMI Specification 2.0 for details.
*
* @since 1.0
*/
enum HdmiColorimetry {
HDMI_COLORIMETRY_NO_DATA = 0,
HDMI_COLORIMETRY_ITU601 = 1,
HDMI_COLORIMETRY_ITU709 = 2,
HDMI_COLORIMETRY_EXTENDED = 3,
};
/**
* @brief Enumerates extended colorimetry, see the section 6.7 of HDMI Specification 1.4 and
* the section 7.2 of HDMI Specification 2.0 for details.
*
* @since 1.0
*/
enum HdmiExtendedColorimetry {
HDMI_EXTENDED_COLORIMETRY_XV_YCC_601 = 0,
HDMI_EXTENDED_COLORIMETRY_XV_YCC_709 = 1,
HDMI_EXTENDED_COLORIMETRY_S_YCC_601 = 2,
HDMI_EXTENDED_COLORIMETRY_OPYCC_601 = 3,
HDMI_EXTENDED_COLORIMETRY_OPRGB = 4,
HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM = 5,
HDMI_EXTENDED_COLORIMETRY_BT2020 = 6,
HDMI_EXTENDED_COLORIMETRY_ADDITIONAL = 7,
HDMI_EXTENDED_COLORIMETRY_BUTT,
};
/**
* @brief Enumerates quantization range, see the section 6.6 of HDMI Specification 1.4 and
* the section 7.3 of HDMI Specification 2.0 for details.
*
* @since 1.0
*/
enum HdmiQuantizationRange {
HDMI_QUANTIZATION_RANGE_DEFAULT = 0,
HDMI_QUANTIZATION_RANGE_LIMITED = 1,
HDMI_QUANTIZATION_RANGE_FULL = 2,
HDMI_QUANTIZATION_RANGE_BUTT,
};
/**
* @brief Enumerates YCC quantization range, see the section 6.6 of HDMI Specification 1.4 and
* the section 7.3 of HDMI Specification 2.0 for details.
*
* @since 1.0
*/
enum HdmiYccQuantizationRange {
HDMI_YCC_QUANTIZATION_RANGE_LIMITED = 0,
HDMI_YCC_QUANTIZATION_RANGE_FULL = 1,
HDMI_YCC_QUANTIZATION_RANGE_BUTT,
};
/**
* @brief Enumerates video 3d structure,
* see the section 8.2.3 of HDMI Specification 1.4 for details.
*
* @since 1.0
*/
enum HdmiVideo3dStructure {
HDMI_VS_VIDEO_3D_FRAME_PACKING = 0,
HDMI_VS_VIDEO_3D_FIELD_ALTERNATIVE = 1,
HDMI_VS_VIDEO_3D_LINE_ALTERNATIVE = 2,
HDMI_VS_VIDEO_3D_SIDE_BY_SIDE_FULL = 3,
HDMI_VS_VIDEO_3D_L_DEPTH = 4,
HDMI_VS_VIDEO_3D_L_DEPTH_GFX_GFX_DEPTH = 5,
HDMI_VS_VIDEO_3D_TOP_AND_BOTTOM = 6,
HDMI_VS_VIDEO_3D_SIDE_BY_SIDE_HALF = 8,
HDMI_VS_VIDEO_3D_BUTT,
};
/**
* @brief Enumerates video timing,
* see the section 8.2.3 of HDMI Specification 1.4 for details.
*
* @since 1.0
*/
enum HdmiVideoTiming {
HDMI_VIDEO_TIMING_NONE = 0,
HDMI_VIDEO_TIMING_640X480P60 = 1,
HDMI_VIDEO_TIMING_720X480P60 = 2,
HDMI_VIDEO_TIMING_720X480P120 = 3,
HDMI_VIDEO_TIMING_720X480P240 = 4,
HDMI_VIDEO_TIMING_720X576P50 = 5,
HDMI_VIDEO_TIMING_720X576P100 = 6,
HDMI_VIDEO_TIMING_720X576P200 = 7,
HDMI_VIDEO_TIMING_1280X720P24 = 8,
HDMI_VIDEO_TIMING_1280X720P25 = 9,
HDMI_VIDEO_TIMING_1280X720P30 = 10,
HDMI_VIDEO_TIMING_1280X720P48 = 11,
HDMI_VIDEO_TIMING_1280X720P50 = 12,
HDMI_VIDEO_TIMING_1280X720P60 = 13,
HDMI_VIDEO_TIMING_1280X720P100 = 14,
HDMI_VIDEO_TIMING_1280X720P120 = 15,
HDMI_VIDEO_TIMING_1440X240P60 = 16,
HDMI_VIDEO_TIMING_1440X288P50 = 17,
HDMI_VIDEO_TIMING_1440X480I60 = 18,
HDMI_VIDEO_TIMING_1440X480P60 = 19,
HDMI_VIDEO_TIMING_1440X480I120 = 20,
HDMI_VIDEO_TIMING_1440X480I240 = 21,
HDMI_VIDEO_TIMING_1440X576I50 = 22,
HDMI_VIDEO_TIMING_1440X576P50 = 23,
HDMI_VIDEO_TIMING_1440X576I60 = 24,
HDMI_VIDEO_TIMING_1440X576I100 = 25,
HDMI_VIDEO_TIMING_1440X576I200 = 26,
HDMI_VIDEO_TIMING_2880X288P50 = 27,
HDMI_VIDEO_TIMING_2880X480I60 = 28,
HDMI_VIDEO_TIMING_2880X480P60 = 29,
HDMI_VIDEO_TIMING_2880X240I60 = 30,
HDMI_VIDEO_TIMING_2880X576I50 = 31,
HDMI_VIDEO_TIMING_2880X576P50 = 32,
HDMI_VIDEO_TIMING_1680X720P24 = 33,
HDMI_VIDEO_TIMING_1680X720P25 = 34,
HDMI_VIDEO_TIMING_1680X720P30 = 35,
HDMI_VIDEO_TIMING_1680X720P48 = 36,
HDMI_VIDEO_TIMING_1680X720P50 = 37,
HDMI_VIDEO_TIMING_1680X720P60 = 38,
HDMI_VIDEO_TIMING_1680X720P100 = 39,
HDMI_VIDEO_TIMING_1680X720P120 = 40,
HDMI_VIDEO_TIMING_2560X1080P24 = 41,
HDMI_VIDEO_TIMING_2560X1080P25 = 42,
HDMI_VIDEO_TIMING_2560X1080P30 = 43,
HDMI_VIDEO_TIMING_2560X1080P48 = 44,
HDMI_VIDEO_TIMING_2560X1080P50 = 45,
HDMI_VIDEO_TIMING_2560X1080P60 = 46,
HDMI_VIDEO_TIMING_2560X1080P100 = 47,
HDMI_VIDEO_TIMING_2560X1080P120 = 48,
HDMI_VIDEO_TIMING_1920X1080I60 = 49,
HDMI_VIDEO_TIMING_1920X1080P60 = 50,
HDMI_VIDEO_TIMING_1920X1080I50 = 51,
HDMI_VIDEO_TIMING_1920X1080P50 = 52,
HDMI_VIDEO_TIMING_1920X1080P24 = 53,
HDMI_VIDEO_TIMING_1920X1080P25 = 54,
HDMI_VIDEO_TIMING_1920X1080P30 = 55,
HDMI_VIDEO_TIMING_1920X1080P48 = 56,
HDMI_VIDEO_TIMING_1920X1080I100 = 57,
HDMI_VIDEO_TIMING_1920X1080I120 = 58,
HDMI_VIDEO_TIMING_1920X1080P120 = 59,
HDMI_VIDEO_TIMING_1920X1080P100 = 60,
HDMI_VIDEO_TIMING_3840X2160P24 = 61,
HDMI_VIDEO_TIMING_3840X2160P25 = 62,
HDMI_VIDEO_TIMING_3840X2160P30 = 63,
HDMI_VIDEO_TIMING_3840X2160P48 = 64,
HDMI_VIDEO_TIMING_3840X2160P50 = 65,
HDMI_VIDEO_TIMING_3840X2160P60 = 66,
HDMI_VIDEO_TIMING_3840X2160P100 = 67,
HDMI_VIDEO_TIMING_3840X2160P120 = 68,
HDMI_VIDEO_TIMING_4096X2160P24 = 69,
HDMI_VIDEO_TIMING_4096X2160P25 = 70,
HDMI_VIDEO_TIMING_4096X2160P30 = 71,
HDMI_VIDEO_TIMING_4096X2160P48 = 72,
HDMI_VIDEO_TIMING_4096X2160P50 = 73,
HDMI_VIDEO_TIMING_4096X2160P60 = 74,
HDMI_VIDEO_TIMING_4096X2160P100 = 75,
HDMI_VIDEO_TIMING_4096X2160P120 = 76,
HDMI_VIDEO_TIMING_5120X2160P24 = 77,
HDMI_VIDEO_TIMING_5120X2160P25 = 78,
HDMI_VIDEO_TIMING_5120X2160P30 = 79,
HDMI_VIDEO_TIMING_5120X2160P48 = 80,
HDMI_VIDEO_TIMING_5120X2160P50 = 81,
HDMI_VIDEO_TIMING_5120X2160P60 = 82,
HDMI_VIDEO_TIMING_5120X2160P100 = 83,
HDMI_VIDEO_TIMING_5120X2160P120 = 84,
HDMI_VIDEO_TIMING_7680X4320P24 = 85,
HDMI_VIDEO_TIMING_7680X4320P25 = 86,
HDMI_VIDEO_TIMING_7680X4320P30 = 87,
HDMI_VIDEO_TIMING_7680X4320P48 = 88,
HDMI_VIDEO_TIMING_7680X4320P50 = 89,
HDMI_VIDEO_TIMING_7680X4320P60 = 90,
HDMI_VIDEO_TIMING_7680X4320P100 = 91,
HDMI_VIDEO_TIMING_7680X4320P120 = 92,
HDMI_VIDEO_TIMING_10240X4320P24 = 93,
HDMI_VIDEO_TIMING_10240X4320P25 = 94,
HDMI_VIDEO_TIMING_10240X4320P30 = 95,
HDMI_VIDEO_TIMING_10240X4320P48 = 96,
HDMI_VIDEO_TIMING_10240X4320P50 = 97,
HDMI_VIDEO_TIMING_10240X4320P60 = 98,
HDMI_VIDEO_TIMING_10240X4320P100 = 99,
HDMI_VIDEO_TIMING_10240X4320P120 = 100,
HDMI_VIDEO_TIMING_VESA_DEFINE = 101,
HDMI_VIDEO_TIMING_VESA_800X600_60 = 102,
HDMI_VIDEO_TIMING_VESA_848X480_60 = 103,
HDMI_VIDEO_TIMING_VESA_1024X768_60 = 104,
HDMI_VIDEO_TIMING_VESA_1280X720_60 = 105,
HDMI_VIDEO_TIMING_VESA_1280X768_60 = 106,
HDMI_VIDEO_TIMING_VESA_1280X768_60_RB = 107,
HDMI_VIDEO_TIMING_VESA_1280X800_60 = 108,
HDMI_VIDEO_TIMING_VESA_1280X800_60_RB = 109,
HDMI_VIDEO_TIMING_VESA_1280X960_60 = 110,
HDMI_VIDEO_TIMING_VESA_1280X1024_60 = 111,
HDMI_VIDEO_TIMING_VESA_1360X768_60 = 112,
HDMI_VIDEO_TIMING_VESA_1366X768_60 = 113,
HDMI_VIDEO_TIMING_VESA_1400X1050_60 = 114,
HDMI_VIDEO_TIMING_VESA_1440X900_60 = 115,
HDMI_VIDEO_TIMING_VESA_1440X900_60_RB = 116,
HDMI_VIDEO_TIMING_VESA_1440X1050_60 = 117,
HDMI_VIDEO_TIMING_VESA_1440X1050_60_RB = 118,
HDMI_VIDEO_TIMING_VESA_1600X900_60_RB = 119,
HDMI_VIDEO_TIMING_VESA_1600X1200_60 = 120,
HDMI_VIDEO_TIMING_VESA_1680X1050_60 = 113,
HDMI_VIDEO_TIMING_VESA_1680X1050_60_RB = 114,
HDMI_VIDEO_TIMING_VESA_1792X1344_60 = 115,
HDMI_VIDEO_TIMING_VESA_1856X1392_60 = 116,
HDMI_VIDEO_TIMING_VESA_1920X1080_60 = 117,
HDMI_VIDEO_TIMING_VESA_1920X1200_60 = 118,
HDMI_VIDEO_TIMING_VESA_1920X1200_60_RB = 119,
HDMI_VIDEO_TIMING_VESA_1920X1440_60 = 120,
HDMI_VIDEO_TIMING_VESA_2048X1152_60 = 121,
HDMI_VIDEO_TIMING_VESA_2560X1440_60_RB = 122,
HDMI_VIDEO_TIMING_VESA_2560X1600_60 = 123,
HDMI_VIDEO_TIMING_VESA_2560X1600_60_RB = 124,
HDMI_VIDEO_TIMING_USER_DEFINE = 125,
HDMI_VIDEO_TIMING_USER_1920X2160_30 = 126,
HDMI_VIDEO_TIMING_USER_2560X1440_30 = 127,
HDMI_VIDEO_TIMING_USER_2560X1440_60 = 128,
HDMI_VIDEO_TIMING_USER_1280X720_60 = 129,
HDMI_VIDEO_TIMING_USER_1366X768_60 = 130,
HDMI_VIDEO_TIMING_USER_1600X900_60_RB = 131,
HDMI_VIDEO_TIMING_USER_1920X1080_60 = 132,
HDMI_VIDEO_TIMING_USER_2048X1152_60 = 133,
HDMI_VIDEO_TIMING_BUTT,
};
/**
* @brief Enumerates picture aspect ratio,
* see the section 8.2.1 of HDMI Specification 1.4 for details.
*
* @since 1.0
*/
enum HdmiPictureAspectRatio {
HDMI_PICTURE_ASPECT_NO_DATA = 0,
HDMI_PICTURE_ASPECT_4_3 = 1,
HDMI_PICTURE_ASPECT_16_9 = 2,
HDMI_PICTURE_ASPECT_64_27 = 3,
HDMI_PICTURE_ASPECT_256_135 = 4,
HDMI_PICTURE_ASPECT_BUTT = 5,
};
/**
* @brief Enumerates active format aspect ratio,
* see the section 8.2.1 of HDMI Specification 1.4 for details.
*
* @since 1.0
*/
enum HdmiActiveFormatAspectRatio {
HDMI_ACTIVE_FORMAT_ASPECT_16_9_TOP = 2,
HDMI_ACTIVE_FORMAT_ASPECT_14_9_TOP = 3,
HDMI_ACTIVE_FORMAT_ASPECT_16_9_CENTER = 4,
HDMI_ACTIVE_FORMAT_ASPECT_PICTURE = 8,
HDMI_ACTIVE_FORMAT_ASPECT_4_3 = 9,
HDMI_ACTIVE_FORMAT_ASPECT_16_9 = 10,
HDMI_ACTIVE_FORMAT_ASPECT_14_9 = 11,
HDMI_ACTIVE_FORMAT_ASPECT_4_3_SP_14_9 = 13,
HDMI_ACTIVE_FORMAT_ASPECT_16_9_SP_14_9 = 14,
HDMI_ACTIVE_FORMAT_ASPECT_16_9_SP_4_3 = 15,
HDMI_ACTIVE_FORMAT_ASPECT_BUTT,
};
/**
* @brief Enumerates Nups(non-uniform picture scaling),
* see the section 8.2.1 of HDMI Specification 1.4 for details.
*
* @since 1.0
*/
enum HdmiNups {
HDMI_NUPS_UNKNOWN = 0, /* No Known non-uniform scaling */
HDMI_NUPS_HORIZONTAL = 1, /* Picture has been scaled horizontally */
HDMI_NUPS_VERTICAL = 2, /* Picture has been scaled vertically */
HDMI_NUPS_BOTH = 3, /* Picture has been scaled horizontally and vertically */
};
struct HdmiVideoAttr {
uint32_t tmdsClock; /* unit: KHz */
uint32_t pixelClock; /* unit: KHz */
uint32_t pixelRepeat;
enum HdmiColorSpace colorSpace;
enum HdmiColorimetry colorimetry;
enum HdmiExtendedColorimetry extColorimetry;
enum HdmiQuantizationRange quantization;
enum HdmiYccQuantizationRange yccQuantization;
enum HdmiDeepColor deepColor;
enum HdmiVideo3dStructure _3dStruct;
enum HdmiVideoTiming timing;
enum HdmiPictureAspectRatio aspect;
enum HdmiActiveFormatAspectRatio activeAspect;
enum HdmiNups nups;
bool xvycc;
};
/**
* @brief Enumerates audio coding type,
* see the section 7 of HDMI Specification 1.4 for details.
*
* @since 1.0
*/
enum HdmiAudioCodingType {
HDMI_AUDIO_CODING_TYPE_STREAM = 0,
HDMI_AUDIO_CODING_TYPE_LPCM = 1,
HDMI_AUDIO_CODING_TYPE_AC3 = 2,
HDMI_AUDIO_CODING_TYPE_MPEG1 = 3,
HDMI_AUDIO_CODING_TYPE_MP3 = 4,
HDMI_AUDIO_CODING_TYPE_MPEG2 = 5,
HDMI_AUDIO_CODING_TYPE_AAC_LC = 6,
HDMI_AUDIO_CODING_TYPE_DTS = 7,
HDMI_AUDIO_CODING_TYPE_ATRAC = 8,
HDMI_AUDIO_CODING_TYPE_OBA =9,
HDMI_AUDIO_CODING_TYPE_EAC3 = 10,
HDMI_AUDIO_CODING_TYPE_DTS_HD = 11,
HDMI_AUDIO_CODING_TYPE_MLP = 12,
HDMI_AUDIO_CODING_TYPE_DST = 13,
HDMI_AUDIO_CODING_TYPE_WMA_PRO = 14,
HDMI_AUDIO_CODING_TYPE_CXT = 15,
};
/**
* @brief Enumerates audio interface type.
*
* @since 1.0
*/
enum HdmiAudioInterfaceType {
HDMI_AUDIO_IF_TYPE_I2S = 0, /* Inter-IC Sound */
HDMI_AUDIO_IF_TYPE_SPDIF = 1, /* Sony/Philips Digital Interface */
HDMI_AUDIO_IF_TYPE_OTHER,
};
/**
* @brief Enumerates audio bit depth,
* see the section 7 of HDMI Specification 1.4 for details.
*
* @since 1.0
*/
enum HdmiAudioBitDepth {
HDMI_ADIO_BIT_DEPTH_UNKNOWN,
HDMI_ADIO_BIT_DEPTH_8 = 8,
HDMI_ADIO_BIT_DEPTH_16 = 16,
HDMI_ADIO_BIT_DEPTH_18 = 18,
HDMI_ADIO_BIT_DEPTH_20 = 20,
HDMI_ADIO_BIT_DEPTH_24 = 24,
HDMI_ADIO_BIT_DEPTH_32 = 32,
HDMI_ADIO_BIT_DEPTH_BUTT,
};
/**
* @brief Enumerates sample rate used for audio,
* see the section 7.3 of HDMI Specification 1.4 for details.
*
* @since 1.0
*/
enum HdmiSampleRate {
HDMI_SAMPLE_RATE_UNKNOWN,
HDMI_SAMPLE_RATE_8K = 8000,
HDMI_SAMPLE_RATE_11K = 11025,
HDMI_SAMPLE_RATE_12K = 12000,
HDMI_SAMPLE_RATE_16K = 16000,
HDMI_SAMPLE_RATE_22K = 22050,
HDMI_SAMPLE_RATE_24K = 24000,
HDMI_SAMPLE_RATE_32K = 32000,
HDMI_SAMPLE_RATE_44K = 44100,
HDMI_SAMPLE_RATE_48K = 48000,
HDMI_SAMPLE_RATE_88K = 88200,
HDMI_SAMPLE_RATE_96K = 96000,
HDMI_SAMPLE_RATE_176K = 176400,
HDMI_SAMPLE_RATE_192K = 192000,
HDMI_SAMPLE_RATE_768K = 768000,
HDMI_SAMPLE_RATE_BUTT,
};
/**
* @brief Enumerates audio format channel,
* see the section 7 of HDMI Specification 1.4 for details.
*
* @since 1.0
*/
enum HdmiAudioFormatChannel {
HDMI_AUDIO_FORMAT_CHANNEL_2 = 2,
HDMI_AUDIO_FORMAT_CHANNEL_3,
HDMI_AUDIO_FORMAT_CHANNEL_4,
HDMI_AUDIO_FORMAT_CHANNEL_5,
HDMI_AUDIO_FORMAT_CHANNEL_6,
HDMI_AUDIO_FORMAT_CHANNEL_7,
HDMI_AUDIO_FORMAT_CHANNEL_8,
HDMI_AUDIO_FORMAT_CHANNEL_BUTT,
};
/**
* @brief Defines the audio Attribute struct.
*
* @since 1.0
*/
struct HdmiAudioAttr {
enum HdmiAudioCodingType codingType;
enum HdmiAudioInterfaceType ifType;
enum HdmiAudioBitDepth bitDepth;
enum HdmiSampleRate sampleRate;
bool downSample;
enum HdmiAudioFormatChannel channels;
};
/* Electro-Optical Transfer Function (EOTF) type define. */
enum HdmiEotfType {
HDMI_DRM_EOTF_SDR_LUMIN = 0, /* Traditional gamma - SDR Luminance Range */
HDMI_DRM_EOTF_HDR_LUMIN = 1, /* Traditional gamma - HDR Luminance Range */
HDMI_DRM_EOTF_SMPTE_ST_2048 = 2, /* SMPTE ST 2048 */
HDMI_DRM_EOTF_HLG = 3, /* Hybrid Log-Gamma (HLG) based on ITU-R BT.2100-0 */
HDMI_DRM_EOTF_BUTT,
};
/**
* @brief Enumerates hdr colormetry,
* see HDMI Specification 2.1 for details.
*
* @since 1.0
*/
enum HdmiHdrColormetry {
HDMI_HDR_COLORIMETRY_NONE,
HDMI_HDR_COLORIMETRY_ITU_601,
HDMI_HDR_COLORIMETRY_ITU_709,
HDMI_HDR_COLORIMETRY_EXTENDED,
HDMI_HDR_EXTENDED_COLORIMETRY_XV_YCC_601,
HDMI_HDR_EXTENDED_COLORIMETRY_XV_YCC_709,
HDMI_HDR_EXTENDED_COLORIMETRY_S_YCC_601,
HDMI_HDR_EXTENDED_COLORIMETRY_ADOBE_YCC_601,
HDMI_HDR_EXTENDED_COLORIMETRY_ADOBE_RGB,
HDMI_HDR_EXTENDED_COLORIMETRY_2020_CONST_LUMINOUS, /* BT2020 c_ycc */
HDMI_HDR_EXTENDED_COLORIMETRY_2020_NON_CONST_LUMINOUW
};
/**
* @brief Enumerates hdr mode,
* see HDMI Specification 2.1 for details.
*
* @since 1.0
*/
enum HdmiHdrMode {
HDMI_HDR_MODE_DISABLE, /* HDR & dolby mode disable */
HDMI_HDR_MODE_DOLBY_NORMAL, /* dolby normal(ycbcr422-12bit) mode enable */
HDMI_HDR_MODE_DOLBY_TUNNELING, /* dolby tunneling(RGB-8bit) mode enable */
HDMI_HDR_MODE_CEA_861_3, /* HDR standard mode enable(according to <CEA-861-3.2015>) */
HDMI_HDR_MODE_CEA_861_3_AUTHEN, /* HDR authen mode */
HDMI_HDR_MODE_BUTT
};
/**
* @brief Enumerates hdr user mode,
* see HDMI Specification 2.1 for details.
*
* @since 1.0
*/
enum HdmiHdrUserMode {
HDMI_HDR_USERMODE_SDR,
HDMI_HDR_USERMODE_HDR10,
HDMI_HDR_USERMODE_DOLBY,
HDMI_HDR_USERMODE_BUTT
};
/**
* @brief Enumerates static metadata type,
* see the section 6.9 of CTA-861-G for details.
*
* @since 1.0
*/
enum HdmiStaticMetadataType {
HDMI_DRM_STATIC_METADATA_TYPE_1 = 0, /* Static Metadata Type 1 */
HDMI_DRM_STATIC_METADATA_BUTT,
};
/**
* @brief Enumerates static metadata descriptor1st,
* see the section 6.9 of CTA-861-G for details.
*
* @since 1.0
*/
struct HdmiStaticMetadataDescriptor1st {
uint16_t displayPrimaries0X; /* display_primaries_x[0], in units of 0.00002 */
uint16_t displayPrimaries0Y; /* display_primaries_y[0], in units of 0.00002 */
uint16_t displayPrimaries1X; /* display_primaries_x[1], in units of 0.00002 */
uint16_t displayPrimaries1Y; /* display_primaries_y[1], in units of 0.00002 */
uint16_t displayPrimaries2X; /* display_primaries_x[2], in units of 0.00002 */
uint16_t displayPrimaries2Y; /* display_primaries_y[2], in units of 0.00002 */
uint16_t whitePointX; /* white_point_x, in units of 0.00002 */
uint16_t whitePointY; /* white_point_y, in units of 0.00002 */
uint16_t maxDisplayMasteringLuminance; /* max_display_mastering_luminance, in units of 1 cd/m^2 */
uint16_t minDisplayMasteringLuminance; /* min_display_mastering_luminance, in units of 0.0001 cd/m^2 */
uint16_t maxContentLightLevel; /* Maximum Content Light Level, in units of 1 cd/m^2 */
uint16_t maxFrameAverageLightLevel; /* Maximum Frame-average Light Level, in units of 1 cd/m^2 */
};
union HdmiStaticMetadataDescriptor {
struct HdmiStaticMetadataDescriptor1st type1;
};
struct HdmiHdrAttr {
enum HdmiHdrMode mode;
enum HdmiHdrUserMode userMode;
/* The following members are valid, when mode is HDMI_HDR_MODE_CEA_861_3. */
enum HdmiEotfType eotfType;
enum HdmiStaticMetadataType metadataType;
union HdmiStaticMetadataDescriptor descriptor;
enum HdmiHdrColormetry colorimetry;
};
/**
* @brief Opens an HDMI controller with a specified bus number.
*
* Before using the HDMI interface, you can obtain the device handle of the HDMI controller
* by calling {@link HdmiOpen}. This function is used in pair with {@link HdmiClose}.
*
* @param busNum Indicates the bus number.
*
* @return Returns the device handle {@link DevHandle} of the HDMI controller if the operation is successful;
* returns <b>NULL</b> otherwise.
*
* @since 1.0
*/
DevHandle HdmiOpen(uint16_t busNum);
/**
* @brief HDMI transmission start.
*
* This function is used in pair with {@link HdmiStop}.
*
* @param handle Indicates the pointer to the device handle of the HDMI controller.
*
* @return Returns <b>0</b> if the operation is successful; returns a negative value if the operation fails.
*
* @since 1.0
*/
int32_t HdmiStart(DevHandle handle);
/**
* @brief HDMI transmission stop.
*
* This function is used in pair with {@link HdmiStart}.
*
* @param handle Indicates the pointer to the device handle of the HDMI controller.
*
* @return Returns <b>0</b> if the operation is successful; returns a negative value if the operation fails.
*
* @since 1.0
*/
int32_t HdmiStop(DevHandle handle);
/**
* @brief HDMI Avmute set.
*
* First put the display device into the black screen mute state, waitting for the HDMI output device switch,
* and then send a Clear AVMute signal, so that the display device to boot, so that the switching process of
* the screen will be shielded.
*
* @param handle Indicates the pointer to the device handle of the HDMI controller.
* @param enable Indicates whether to enable avmute.
*
* @return Returns <b>0</b> if the operation is successful; returns a negative value if the operation fails.
*
* @since 1.0
*/
int32_t HdmiAvmuteSet(DevHandle handle, bool enable);
/**
* @brief HDMI deep color set.
*
* @param handle Indicates the pointer to the device handle of the HDMI controller.
* @param color Indicates the deep color to be set, see {@link HdmiDeepColor}.
*
* @return Returns <b>0</b> if the operation is successful; returns a negative value if the operation fails.
*
* @since 1.0
*/
int32_t HdmiDeepColorSet(DevHandle handle, enum HdmiDeepColor color);
/**
* @brief HDMI deep color get.
*
* @param handle Indicates the pointer to the device handle of the HDMI controller.
* @param color Indicates the pointer to the deep color to read, see {@link HdmiDeepColor}.
*
* @return Returns <b>0</b> if the operation is successful; returns a negative value if the operation fails.
*
* @since 1.0
*/
int32_t HdmiDeepColorGet(DevHandle handle, enum HdmiDeepColor *color);
/**
* @brief HDMI set video attribute.
*
* @param handle Indicates the pointer to the device handle of the HDMI controller.
* @param attr Indicates the pointer to the video attribute to set, see {@link HdmiVideoAttr}.
*
* @return Returns <b>0</b> if the operation is successful; returns a negative value if the operation fails.
*
* @since 1.0
*/
int32_t HdmiSetVideoAttribute(DevHandle handle, struct HdmiVideoAttr *attr);
/**
* @brief HDMI set audio attribute.
*
* @param handle Indicates the pointer to the device handle of the HDMI controller.
* @param attr Indicates the pointer to the audio attribute to set, see {@link HdmiAudioAttr}.
*
* @return Returns <b>0</b> if the operation is successful; returns a negative value if the operation fails.
*
* @since 1.0
*/
int32_t HdmiSetAudioAttribute(DevHandle handle, struct HdmiAudioAttr *attr);
/**
* @brief HDMI set hdr attribute.
*
* @param handle Indicates the pointer to the device handle of the HDMI controller.
* @param attr Indicates the pointer to the hdr attribute to set, see {@link HdmiHdrAttr}.
*
* @return Returns <b>0</b> if the operation is successful; returns a negative value if the operation fails.
*
* @since 1.0
*/
int32_t HdmiSetHdrAttribute(DevHandle handle, struct HdmiHdrAttr *attr);
/**
* @brief HDMI read sink device's raw EDID data.
*
* @param handle Indicates the pointer to the device handle of the HDMI controller.
* @param buffer Indicates the pointer to the data to read.
* @param len Indicates the length of the data to read.
*
* @return Returns the length of the data read if the operation is successful;
* returns a negative value or 0 if the operation fails.
*
* @since 1.0
*/
int32_t HdmiReadSinkEdid(DevHandle handle, uint8_t *buffer, uint32_t len);
/**
* @brief Closes an HDMI controller.
*
* After the HDMI interface is used, you can close the HDMI controller by calling {@link HdmiClose}.
* This function is used in pair with {@link HdmiOpen}.
*
* @param handle Indicates the pointer to the device handle of the HDMI controller.
*
* @since 1.0
*/
void HdmiClose(DevHandle handle);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* HDMI_IF_H */
File diff suppressed because it is too large Load Diff
+348
View File
@@ -0,0 +1,348 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef HDMI_COMMON_H
#define HDMI_COMMON_H
#include "hdf_base.h"
#include "hdmi_if.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
#define HDMI_CEA_VIDEO_CODE_MAX 44
#define HDMI_VESA_VIDEO_CODE_MAX 31
#define HDMI_VIDEO_4K_CODES_MAX 4
#define HDMI_HDMI14_MAX_TMDS_RATE 340000 /* unit: KHz */
#define HDMI_HDMI20_MAX_TMDS_RATE 600000 /* unit: KHz */
#define HDMI_MULTIPLE_2P0(x) (2 * x)
#define HDMI_MULTIPLE_1P5(x) (((x) * 3) >> 1)
#define HDMI_MULTIPLE_1P25(x) (((x) * 5) >> 2)
#define HDMI_MULTIPLE_0P5(x) ((x) >> 1)
enum HdmiTmdsModeType {
HDMI_TMDS_MODE_NULL = 0,
HDMI_TMDS_MODE_DVI = 1,
HDMI_TMDS_MODE_HDMI_1_4 = 2,
HDMI_TMDS_MODE_HDMI_2_0 = 3,
HDMI_TMDS_MODE_AUTO = 4,
HDMI_TMDS_MODE_HDMI_2_1 = 5,
HDMI_TMDS_MODE_BUTT,
};
/*
* Video Identification Code (VIC).
* see CTA-861-G, table 3.
*/
enum HdmiVic {
HDMI_VIC_NONE = 0, /* No Video Identification Code Avaiable(Used with AVI Infoframe only) */
HDMI_VIC_640X480P60_4_3 = 1,
HDMI_VIC_720X480P60_4_3 = 2,
HDMI_VIC_720X480P60_16_9 = 3,
HDMI_VIC_1280X720P60_16_9 = 4,
HDMI_VIC_1920X1080I60_16_9 = 5,
HDMI_VIC_1440X480I60_4_3 = 6,
HDMI_VIC_1440X480I60_16_9 = 7,
HDMI_VIC_1440X240P60_4_3 = 8,
HDMI_VIC_1440X240P60_16_9 = 9,
HDMI_VIC_2880X480I60_4_3 = 10,
HDMI_VIC_2880X480I60_16_9 = 11,
HDMI_VIC_2880X240P60_4_3 = 12,
HDMI_VIC_2880X240P60_16_9 = 13,
HDMI_VIC_1440X480P60_4_3 = 14,
HDMI_VIC_1440X480P60_16_9 = 15,
HDMI_VIC_1920X1080P60_16_9 = 16,
HDMI_VIC_720X576P50_4_3 = 17,
HDMI_VIC_720X576P50_16_9 = 18,
HDMI_VIC_1280X720P50_16_9 = 19,
HDMI_VIC_1920X1080I50_16_9 = 20,
HDMI_VIC_1440X576I50_4_3 = 21,
HDMI_VIC_1440X576I50_16_9 = 22,
HDMI_VIC_1440X288P50_4_3 = 23,
HDMI_VIC_1440X288P50_16_9 = 24,
HDMI_VIC_2880X576I50_4_3 = 25,
HDMI_VIC_2880X576I50_16_9 = 26,
HDMI_VIC_2880X288P50_4_3 = 27,
HDMI_VIC_2880X288P50_16_9 = 28,
HDMI_VIC_1440X576P50_4_3 = 29,
HDMI_VIC_1440X576P50_16_9 = 30,
HDMI_VIC_1920X1080P50_16_9 = 31,
HDMI_VIC_1920X1080P24_16_9 = 32,
HDMI_VIC_1920X1080P25_16_9 = 33,
HDMI_VIC_1920X1080P30_16_9 = 34,
HDMI_VIC_2880X480P60_4_3 = 35,
HDMI_VIC_2880X480P60_16_9 = 36,
HDMI_VIC_2880X576P50_4_3 = 37,
HDMI_VIC_2880X576P50_16_9 = 38,
HDMI_VIC_1920X1080I50_1250_16_9 = 39,
HDMI_VIC_1920X1080I100_16_9 = 40,
HDMI_VIC_1280X720P100_16_9 = 41,
HDMI_VIC_720X576P100_4_3 = 42,
HDMI_VIC_720X576P100_16_9 = 43,
HDMI_VIC_1440X576I100_4_3 = 44,
HDMI_VIC_1440X576I100_16_9 = 45,
HDMI_VIC_1920X1080I120_16_9 = 46,
HDMI_VIC_1280X720P120_16_9 = 47,
HDMI_VIC_720X480P120_4_3 = 48,
HDMI_VIC_720X480P120_16_9 = 49,
HDMI_VIC_1440X480I120_4_3 = 50,
HDMI_VIC_1440X480I120_16_9 = 51,
HDMI_VIC_720X576P200_4_3 = 52,
HDMI_VIC_720X576P200_16_9 = 53,
HDMI_VIC_1440X576I120_4_3 = 54,
HDMI_VIC_1440X576I120_16_9 = 55,
HDMI_VIC_720X480P240_4_3 = 56,
HDMI_VIC_720X480P240_16_9 = 57,
HDMI_VIC_1440X480I240_4_3 = 58,
HDMI_VIC_1440X480I240_16_9 = 59,
HDMI_VIC_1280X720P24_16_9 = 60,
HDMI_VIC_1280X720P25_16_9 = 61,
HDMI_VIC_1280X720P30_16_9 = 62,
HDMI_VIC_1920X1080P120_16_9 = 63,
HDMI_VIC_1920X1080P100_16_9 = 64,
HDMI_VIC_1280X720P24_64_27 = 65,
HDMI_VIC_1280X720P25_64_27 = 66,
HDMI_VIC_1280X720P30_64_27 = 67,
HDMI_VIC_1280X720P50_64_27 = 68,
HDMI_VIC_1280X720P60_64_27 = 69,
HDMI_VIC_1280X720P100_64_27 = 70,
HDMI_VIC_1280X720P120_64_27 = 71,
HDMI_VIC_1920X1080P24_64_27 = 72,
HDMI_VIC_1920X1080P25_64_27 = 73,
HDMI_VIC_1920X1080P30_64_27 = 74,
HDMI_VIC_1920X1080P50_64_27 = 75,
HDMI_VIC_1920X1080P60_64_27 = 76,
HDMI_VIC_1920X1080P100_64_27 = 77,
HDMI_VIC_1920X1080P120_64_27 = 78,
HDMI_VIC_1680X720P24_64_27 = 79,
HDMI_VIC_1680X720P25_64_27 = 80,
HDMI_VIC_1680X720P30_64_27 = 81,
HDMI_VIC_1680X720P50_64_27 = 82,
HDMI_VIC_1680X720P60_64_27 = 83,
HDMI_VIC_1680X720P100_64_27 = 84,
HDMI_VIC_1680X720P120_64_27 = 85,
HDMI_VIC_2560X1080P24_64_27 = 86,
HDMI_VIC_2560X1080P25_64_27 = 87,
HDMI_VIC_2560X1080P30_64_27 = 88,
HDMI_VIC_2560X1080P50_64_27 = 89,
HDMI_VIC_2560X1080P60_64_27 = 90,
HDMI_VIC_2560X1080P100_64_27 = 91,
HDMI_VIC_2560X1080P120_64_27 = 92,
HDMI_VIC_3840X2160P24_16_9 = 93,
HDMI_VIC_3840X2160P25_16_9 = 94,
HDMI_VIC_3840X2160P30_16_9 = 95,
HDMI_VIC_3840X2160P50_16_9 = 96,
HDMI_VIC_3840X2160P60_16_9 = 97,
HDMI_VIC_4096X2160P24_256_135 = 98,
HDMI_VIC_4096X2160P25_256_135 = 99,
HDMI_VIC_4096X2160P30_256_135 = 100,
HDMI_VIC_4096X2160P50_256_135 = 101,
HDMI_VIC_4096X2160P60_256_135 = 102,
HDMI_VIC_3840X2160P24_64_27 = 103,
HDMI_VIC_3840X2160P25_64_27 = 104,
HDMI_VIC_3840X2160P30_64_27 = 105,
HDMI_VIC_3840X2160P50_64_27 = 106,
HDMI_VIC_3840X2160P60_64_27 = 107,
HDMI_VIC_1280X720P48_16_9 = 108,
HDMI_VIC_1280X720P48_64_27 = 109,
HDMI_VIC_1680X720P48_64_27 = 110,
HDMI_VIC_1920X1080P48_16_9 = 111,
HDMI_VIC_1920X1080P48_64_27 = 112,
HDMI_VIC_2560X1080P48_64_27 = 113,
HDMI_VIC_3840X2160P48_16_9 = 114,
HDMI_VIC_4096X2160P48_256_135 = 115,
HDMI_VIC_3840X2160P48_64_27 = 116,
HDMI_VIC_3840X2160P100_16_9 = 117,
HDMI_VIC_3840X2160P120_16_9 = 118,
HDMI_VIC_3840X2160P100_64_27 = 119,
HDMI_VIC_3840X2160P120_64_27 = 120,
HDMI_VIC_5120X2160P24_64_27 = 121,
HDMI_VIC_5120X2160P25_64_27 = 122,
HDMI_VIC_5120X2160P30_64_27 = 123,
HDMI_VIC_5120X2160P48_64_27 = 124,
HDMI_VIC_5120X2160P50_64_27 = 125,
HDMI_VIC_5120X2160P60_64_27 = 126,
HDMI_VIC_5120X2160P100_64_27 = 127,
HDMI_VIC_5120X2160P120_64_27 = 193,
HDMI_VIC_7680X4320P24_16_9 = 194,
HDMI_VIC_7680X4320P25_16_9 = 195,
HDMI_VIC_7680X4320P30_16_9 = 196,
HDMI_VIC_7680X4320P48_16_9 = 197,
HDMI_VIC_7680X4320P50_16_9 = 198,
HDMI_VIC_7680X4320P60_16_9 = 199,
HDMI_VIC_7680X4320P100_16_9 = 200,
HDMI_VIC_7680X4320P120_16_9 = 201,
HDMI_VIC_7680X4320P24_64_27 = 202,
HDMI_VIC_7680X4320P25_164_27 = 203,
HDMI_VIC_7680X4320P30_64_27 = 204,
HDMI_VIC_7680X4320P48_64_27 = 205,
HDMI_VIC_7680X4320P50_64_27 = 206,
HDMI_VIC_7680X4320P60_64_27 = 207,
HDMI_VIC_7680X4320P100_64_27 = 208,
HDMI_VIC_7680X4320P120_64_27 = 209,
HDMI_VIC_10240X4320P24_64_27 = 210,
HDMI_VIC_10240X4320P25_64_27 = 211,
HDMI_VIC_10240X4320P30_64_27 = 212,
HDMI_VIC_10240X4320P48_64_27 = 213,
HDMI_VIC_10240X4320P50_64_27 = 214,
HDMI_VIC_10240X4320P60_64_27 = 215,
HDMI_VIC_10240X4320P100_64_27 = 216,
HDMI_VIC_10240X4320P120_64_27 = 217,
HDMI_VIC_4096X2160P100_256_135 = 218,
HDMI_VIC_4096X2160P120_256_135 = 219,
};
enum HdmiVideoFormatType {
HDMI_VIDEO_FORMAT_NULL = 0,
HDMI_VIDEO_FORMAT_PROGRESSIVE = 1,
HDMI_VIDEO_FORMA_INTERLACE = 2,
HDMI_VIDEO_FORMA_BUTT,
};
enum HdmiColorDeep {
HDMI_COLOR_DEEP_8BITS = 8,
HDMI_COLOR_DEEP_10BITS = 10,
HDMI_COLOR_DEEP_12BITS = 12,
HDMI_COLOR_DEEP_16BITS = 16,
HDMI_COLOR_DEEP_BUTT,
};
enum HdmiPhyModeCfg {
HDMI_PHY_MODE_TMDS = 0,
HDMI_PHY_MODE_FRL = 1,
HDMI_PHY_MODE_TXFFE = 2,
HDMI_PHY_MODE_BUTT,
};
enum HdmiHdcpMode {
HDMI_HDCP_MODE_AUTO = 0,
HDMI_HDCP_MODE_1_4 = 1,
HDMI_HDCP_MODE_2_2 = 2,
HDMI_HDCP_MODE_BUTT
};
struct HdmiVideoDefInfo {
enum HdmiVic vic;
uint32_t pixclk;
uint32_t rate;
uint32_t hactive;
uint32_t vactive;
uint32_t hblank;
uint32_t vblank;
uint32_t hfront;
uint32_t hsync;
uint32_t hback;
uint32_t vfront;
uint32_t vsync;
uint32_t vback;
enum HdmiPictureAspectRatio aspect;
enum HdmiVideoTiming timing;
enum HdmiVideoFormatType formatType;
};
/* see hdmi spec2.0 table 10-2. */
enum Hdmi4kVic {
HDMI_4K_VIC_3840X2160_30 = 1,
HDMI_4K_VIC_3840X2160_25,
HDMI_4K_VIC_3840X2160_24,
HDMI_4K_VIC_4096X2160_24
};
struct HdmiVideo4kInfo {
enum Hdmi4kVic _4kVic;
enum HdmiVic vic;
uint32_t pixclk;
uint32_t rate;
uint32_t hactive;
uint32_t vactive;
enum HdmiPictureAspectRatio aspect;
enum HdmiVideoTiming timing;
enum HdmiVideoFormatType formatType;
};
struct HdmiCommonStatus {
bool hotplug;
bool avmute;
bool sinkPowerOn;
enum HdmiTmdsModeType tmdsMode;
};
struct HdmiAudioStatus {
bool mute;
bool enable;
bool downSample;
enum HdmiSampleRate sampleRate;
enum HdmiAudioInterfaceType interface;
enum HdmiAudioBitDepth bitDepth;
enum HdmiAudioFormatChannel channel;
uint32_t refN;
uint32_t regN;
uint32_t refCts;
uint32_t regCts;
};
struct HdmiVideoStatus {
bool mute;
bool ycbcr2Rgb;
bool rgb2Ycbcr;
bool ycbcr444422;
bool ycbcr422420;
bool ycbcr420422;
bool ycbcr422444;
bool in420Ydemux;
bool out420Ydemux;
bool vSyncPol;
bool hSyncPol;
bool syncPol;
bool dePol;
bool swapHsCs;
enum HdmiColorSpace inColorSpace;
enum HdmiColorSpace outColorSpace;
enum HdmiVideoBitDepth outBitDepth;
enum HdmiQuantizationRange quantization;
};
struct HdmiCommonAttr {
bool enableHdmi;
bool enableVideo;
bool enableAudio;
bool xvyccMode;
bool avi;
bool spd;
bool mpeg;
bool audio;
bool drm;
bool hdcpEnable;
bool vsifDolby;
enum HdmiColorSpace colorSpace;
enum HdmiQuantizationRange quantization;
enum HdmiDeepColor deepColor;
enum HdmiHdcpMode hdcpMode;
};
enum HdmiVideoBitDepth HdmiCommonDeepClolorConvertToColorDepth(enum HdmiDeepColor deepColor);
enum HdmiDeepColor HdmiCommonColorDepthConvertToDeepClolor(enum HdmiVideoBitDepth colorDepth);
enum HdmiVic HdmiCommonGetVic(enum HdmiVideoTiming timing,
enum HdmiPictureAspectRatio aspect, bool enable3d);
struct HdmiVideoDefInfo *HdmiCommonGetVideoDefInfo(enum HdmiVideoTiming timing,
enum HdmiPictureAspectRatio aspect, bool enable3d);
struct HdmiVideo4kInfo *HdmiCommonGetVideo4kInfo(uint32_t _4kVic);
enum HdmiVideoTiming HdmiCommonGetVideoTiming(enum HdmiVic vic, enum HdmiPictureAspectRatio aspect);
enum HdmiVideoTiming HdmiCommonGetVideo4kTiming(uint32_t _4kVic);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* HDMI_COMMON_H */
+388
View File
@@ -0,0 +1,388 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef HDMI_CORE_H
#define HDMI_CORE_H
#include "hdf_base.h"
#include "hdf_device_desc.h"
#include "hdmi_cec.h"
#include "hdmi_common.h"
#include "hdmi_ddc.h"
#include "hdmi_edid.h"
#include "hdmi_event.h"
#include "hdmi_frl.h"
#include "hdmi_hdcp.h"
#include "hdmi_hdr.h"
#include "hdmi_if.h"
#include "hdmi_infoframe.h"
#include "hdmi_scdc.h"
#include "osal_mutex.h"
#include "platform_core.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
#define HDMI_ONE_BYTE_MARK 0xFF
#define HDMI_ONE_BYTE_SHIFT 8
#define HDMI_TWO_BYTES_SHIFT 16
struct HdmiPhyCfg {
uint32_t pixelClk;
uint32_t tmdsClk; /* TMDS colck, KHz */
enum HdmiDeepColor deepColor; /* deep color(color depth) */
enum HdmiPhyModeCfg modeCfg; /* TMDS/FRL/tx_ffe */
enum HdmiColorSpace colorSpace;
enum HdmiFrlWorkMode rate; /* lane and rate */
enum HdmiFrlTxffeMode txffe[4]; /* tx_ffe */
};
struct HdmiTmdsConfig {
uint32_t pixelClk;
uint32_t tmdsClk;
enum HdmiPhyModeCfg mode;
enum HdmiDeepColor deepColor;
};
struct HdmiCntlr;
union HdmiCap {
uint32_t data;
struct CapBitsData {
uint32_t scdc : 1; /* bit0: support scdc */
uint32_t frl : 1; /* bit1: support frl */
uint32_t hdr : 1; /* bit2: support hdr */
uint32_t hdcp: 1; /* bit3: support hdcp */
uint32_t cec : 1; /* bit4: support cec */
uint32_t hdmi14 : 1; /* bit5: support hdmi1.4 spec */
uint32_t hdmi20 : 1; /* bit6: support hdmi2.0 spec */
uint32_t hdmi21 : 1; /* bit7: support hdmi2.1 spec */
uint32_t hdcp14 : 1; /* bit8: support hdcp1.4 spec */
uint32_t hdcp22 : 1; /* bit9: support hdcp2.2 spec */
uint32_t rgb444 : 1; /* bit10: support rgb444 */
uint32_t ycbcr444 : 1; /* bit11: support ycbcr444 */
uint32_t ycbcr422 : 1; /* bit12: support ycbcr422 */
uint32_t ycbcr420 : 1; /* bit13: support ycbcr420 */
uint32_t deepColor10bits: 1; /* bit14: support deep color 10 bits */
uint32_t deepColor12bits: 1; /* bit15: support deep color 12 bits */
uint32_t deepColor16bits: 1; /* bit16: support deep color 16 bits */
uint32_t scramble : 1; /* bit17: support scramble */
uint32_t cecRc : 1; /* bit18: support CEC Remote Control */
uint32_t rev : 13; /* bit21~31: reserved */
} bits;
};
enum HdmiCapMark {
HDMI_CAP_SCDC_MARK = (1 << 0),
HDMI_CAP_FRL_MARK = (1 << 1),
HDMI_CAP_HDR_MARK = (1 << 2),
HDMI_CAP_HDCP_MARK = (1 << 3),
HDMI_CAP_CEC_MARK = (1 << 4),
HDMI_CAP_HDMI14_MARK = (1 << 5),
HDMI_CAP_HDMI20_MARK = (1 << 6),
HDMI_CAP_HDMI21_MARK = (1 << 7),
HDMI_CAP_HDCP14_MARK = (1 << 8),
HDMI_CAP_HDCP22_MARK = (1 << 9),
HDMI_CAP_RGB444_MARK = (1 << 10),
HDMI_CAP_YCBCR444_MARK = (1 << 11),
HDMI_CAP_YCBCR422_MARK = (1 << 12),
HDMI_CAP_YCBCR420_MARK = (1 << 13),
HDMI_CAP_DEEP_COLOR_10BITES_MARK = (1 << 14),
HDMI_CAP_DEEP_COLOR_12BITES_MARK = (1 << 15),
HDMI_CAP_DEEP_COLOR_16BITES_MARK = (1 << 16),
HDMI_CAP_SCRAMBLE_MARK = (1 << 17),
};
struct HdmiCntlrCap {
union HdmiCap baseCap;
uint32_t maxTmdsClock;
uint32_t defTmdsClock; /* unit: MHz */
uint32_t maxFrlRate;
uint32_t videoTiming;
uint32_t quantization;
uint32_t colorSpace;
uint32_t colorimetry;
uint32_t audioIfType;
uint32_t audioBitDepth;
uint32_t audioSampleRate;
uint32_t audioChannels;
uint32_t hdrColorimetry;
uint32_t hdrUserMode;
};
struct HdmiHardwareStatus {
struct HdmiCommonStatus commonStatus;
struct HdmiAudioStatus audioStatus;
struct HdmiVideoStatus videoStatus;
struct HdmiInfoframeStatus infoframeStatus;
struct HdmiHdcpStatus hdcpstatus;
};
struct HdmiAudioConfigInfo {
bool enable;
bool downSample;
uint32_t tmdsClock;
uint32_t pixelRepeat;
enum HdmiAudioInterfaceType ifType;
enum HdmiAudioBitDepth bitDepth;
enum HdmiSampleRate sampleRate;
enum HdmiAudioFormatChannel channels;
};
struct HdmiCntlrOps {
void (*hardWareInit)(struct HdmiCntlr *cntlr);
void (*hardWareStatusGet)(struct HdmiCntlr *cntlr, struct HdmiHardwareStatus *status);
void (*controllerReset)(struct HdmiCntlr *cntlr);
bool (*hotPlugStateGet)(struct HdmiCntlr *cntlr);
bool (*hotPlugInterruptStateGet)(struct HdmiCntlr *cntlr);
void (*lowPowerSet)(struct HdmiCntlr *cntlr, bool enable);
void (*tmdsModeSet)(struct HdmiCntlr *cntlr, enum HdmiTmdsModeType mode);
int32_t (*tmdsConfigSet)(struct HdmiCntlr *cntlr, struct HdmiTmdsConfig mode);
void (*infoframeEnable)(struct HdmiCntlr *cntlr, enum HdmiPacketType infoframeType, bool enable);
int32_t (*infoframeSend)(struct HdmiCntlr *cntlr, enum HdmiPacketType infoframeType, uint8_t *data, uint32_t len);
int32_t (*infoframeDataSet)(struct HdmiCntlr *cntlr, uint32_t type, uint8_t *data, uint32_t len);
int32_t (*cecMsgSend)(struct HdmiCntlr *cntlr, struct HdmiCecMsg *msg);
void (*audioPathEnable)(struct HdmiCntlr *cntlr, bool enable);
void (*audioPathSet)(struct HdmiCntlr *cntlr, struct HdmiAudioConfigInfo *config);
void (*phyOutputEnable)(struct HdmiCntlr *cntlr, bool enable);
void (*phyOutputSet)(struct HdmiCntlr *cntlr, struct HdmiPhyCfg *cfg);
void (*blackDataSet)(struct HdmiCntlr *cntlr, bool enable);
void (*videoMuteEnable)(struct HdmiCntlr *cntlr, bool enable);
void (*videoPathSet)(struct HdmiCntlr *cntlr, struct HdmiVideoAttr *attr);
void (*audioMuteEnable)(struct HdmiCntlr *cntlr, bool enable);
void (*avmuteSet)(struct HdmiCntlr *cntlr, bool enable);
int32_t (*ddcTransfer)(struct HdmiCntlr *cntlr, struct HdmiDdcCfg *ddcCfg);
bool (*scdcSourceScrambleGet)(struct HdmiCntlr *cntlr);
int32_t (*scdcSourceScrambleSet)(struct HdmiCntlr *cntlr, bool enable);
void (*frlSet)(struct HdmiCntlr *cntlr);
int32_t (*frlEnable)(struct HdmiCntlr *cntlr, bool enable);
int32_t (*audioNctsSet)(struct HdmiCntlr *cntlr, struct HdmiFrlAudioNctsConfig *cfg);
void (*frlTrainingConfigSet)(struct HdmiCntlr *cntlr, struct HdmiFrlTrainConfig *cfg);
void (*frlTrainingStart)(struct HdmiCntlr *cntlr);
void (*frlGetTriningRslt)(struct HdmiCntlr *cntlr, struct HdmiFrlTrainRslt *rslt);
void (*hdcpRegInit)(struct HdmiCntlr *cntlr);
int32_t (*hdcpGenerateAksvAndAn)(struct HdmiCntlr *cntlr);
int32_t (*hdcpOptReg)(struct HdmiCntlr *cntlr, enum HdmiHdcpRegOptType type, uint8_t *data, uint32_t len);
void (*hdrTimerSet)(struct HdmiCntlr *cntlr, struct HdmiHdrTimerConfig *config);
};
enum HdmiCntlrState {
HDMI_CNTLR_STATE_NONE = 0,
HDMI_CNTLR_STATE_OPEN = (1 << 0),
HDMI_CNTLR_STATE_START = (1 << 1),
HDMI_CNTLR_STATE_STOP = (1 << 2),
HDMI_CNTLR_STATE_CLOSE = (1 << 3),
};
struct HdmiDevice {
struct HdmiEdid edid; /* device cap */
struct HdmiCntlr *cntlr;
void *priv;
};
struct HdmiAttr {
struct HdmiCommonAttr commAttr;
struct HdmiAudioAttr audioAttr;
struct HdmiVideoAttr videoAttr;
struct HdmiHdrAttr hdrAttr;
};
struct HdmiCntlr {
struct IDeviceIoService service;
struct HdfDeviceObject *hdfDevObj;
struct PlatformDevice device;
struct OsalMutex mutex;
struct PlatformQueue *msgQueue;
struct HdmiCntlrCap cap;
struct HdmiAttr attr;
struct HdmiCntlrOps *ops;
uint32_t deviceIndex;
uint32_t state; /* cntlr state. */
enum HdmiTmdsModeType tmdsMode;
struct HdmiDevice *hdmi;
struct HdmiInfoframe infoframe;
struct HdmiScdc *scdc;
struct HdmiDdc ddc;
struct HdmiFrl *frl;
struct HdmiHdcp *hdcp;
struct HdmiCec *cec;
struct HdmiEvent event;
struct HdmiHdr *hdr;
void *priv;
};
static inline void HdmiCntlrLock(struct HdmiCntlr *cntlr)
{
if (cntlr != NULL) {
(void)OsalMutexLock(&cntlr->mutex);
}
}
static inline void HdmiCntlrUnlock(struct HdmiCntlr *cntlr)
{
if (cntlr != NULL) {
(void)OsalMutexUnlock(&cntlr->mutex);
}
}
static inline struct HdmiCntlr *HdmiCntlrGetByBusNum(uint16_t num)
{
struct PlatformDevice *device = PlatformManagerGetDeviceByMagic(PlatformManagerGet(PLATFORM_MODULE_HDMI), num);
if (device == NULL) {
return NULL;
}
return CONTAINER_OF(device, struct HdmiCntlr, device);
}
static inline void HdmiCntlrLowPowerSet(struct HdmiCntlr *cntlr, bool enable)
{
if (cntlr->ops != NULL && cntlr->ops->lowPowerSet != NULL) {
HdmiCntlrLock(cntlr);
cntlr->ops->lowPowerSet(cntlr, enable);
HdmiCntlrUnlock(cntlr);
}
}
static inline void HdmiCntlrHardWareInit(struct HdmiCntlr *cntlr)
{
if (cntlr->ops != NULL && cntlr->ops->hardWareInit != NULL) {
HdmiCntlrLock(cntlr);
cntlr->ops->hardWareInit(cntlr);
HdmiCntlrUnlock(cntlr);
}
}
static inline void HdmiCntlrAudioPathEnable(struct HdmiCntlr *cntlr, bool enable)
{
if (cntlr->ops != NULL && cntlr->ops->audioPathEnable != NULL) {
HdmiCntlrLock(cntlr);
cntlr->ops->audioPathEnable(cntlr, enable);
HdmiCntlrUnlock(cntlr);
}
}
static inline void HdmiCntlrAudioPathSet(struct HdmiCntlr *cntlr, struct HdmiAudioConfigInfo *config)
{
if (cntlr->ops != NULL && cntlr->ops->audioPathSet != NULL) {
HdmiCntlrLock(cntlr);
cntlr->ops->audioPathSet(cntlr, config);
HdmiCntlrUnlock(cntlr);
}
}
static inline void HdmiCntlrAudioMuteEnable(struct HdmiCntlr *cntlr, bool enable)
{
if (cntlr->ops != NULL && cntlr->ops->audioMuteEnable != NULL) {
HdmiCntlrLock(cntlr);
cntlr->ops->audioMuteEnable(cntlr, enable);
HdmiCntlrUnlock(cntlr);
}
}
static inline void HdmiCntlrVideoPathSet(struct HdmiCntlr *cntlr, struct HdmiVideoAttr *attr)
{
if (cntlr->ops != NULL && cntlr->ops->videoPathSet != NULL) {
HdmiCntlrLock(cntlr);
cntlr->ops->videoPathSet(cntlr, attr);
HdmiCntlrUnlock(cntlr);
}
}
static inline void HdmiCntlrTmdsModeSet(struct HdmiCntlr *cntlr, enum HdmiTmdsModeType mode)
{
if (cntlr->ops != NULL && cntlr->ops->tmdsModeSet != NULL) {
HdmiCntlrLock(cntlr);
cntlr->ops->tmdsModeSet(cntlr, mode);
HdmiCntlrUnlock(cntlr);
}
}
static inline void HdmiCntlrReset(struct HdmiCntlr *cntlr)
{
if (cntlr->ops != NULL && cntlr->ops->controllerReset != NULL) {
HdmiCntlrLock(cntlr);
cntlr->ops->controllerReset(cntlr);
HdmiCntlrUnlock(cntlr);
}
}
static inline void HdmiCntlrBlackDataSet(struct HdmiCntlr *cntlr, bool enable)
{
if (cntlr->ops != NULL && cntlr->ops->blackDataSet != NULL) {
HdmiCntlrLock(cntlr);
cntlr->ops->blackDataSet(cntlr, enable);
HdmiCntlrUnlock(cntlr);
}
}
static inline void HdmiCntlrPhyOutputEnablet(struct HdmiCntlr *cntlr, bool enable)
{
if (cntlr->ops != NULL && cntlr->ops->phyOutputEnable != NULL) {
HdmiCntlrLock(cntlr);
cntlr->ops->phyOutputEnable(cntlr, enable);
HdmiCntlrUnlock(cntlr);
}
}
static inline void HdmiCntlrHdrTimerSet(struct HdmiCntlr *cntlr, struct HdmiHdrTimerConfig *config)
{
if (cntlr->ops != NULL && cntlr->ops->hdrTimerSet != NULL) {
HdmiCntlrLock(cntlr);
cntlr->ops->hdrTimerSet(cntlr, config);
HdmiCntlrUnlock(cntlr);
}
}
static inline void HdmiCntlrAvmuteSet(struct HdmiCntlr *cntlr, bool enable)
{
if (cntlr->ops != NULL && cntlr->ops->avmuteSet != NULL) {
HdmiCntlrLock(cntlr);
cntlr->ops->avmuteSet(cntlr, enable);
HdmiCntlrUnlock(cntlr);
}
}
int32_t HdmiCntlrParse(struct HdmiCntlr *cntlr, struct HdfDeviceObject *obj);
int32_t HdmiCntlrAdd(struct HdmiCntlr *cntlr);
void HdmiCntlrRemove(struct HdmiCntlr *cntlr);
int32_t HdmiCntlrOpen(struct HdmiCntlr *cntlr);
int32_t HdmiCntlrGetSinkEdid(struct HdmiCntlr *cntlr, uint8_t *buffer, uint32_t len);
int32_t HdmiCntlrStart(struct HdmiCntlr *cntlr);
int32_t HdmiCntlrStop(struct HdmiCntlr *cntlr);
int32_t HdmiCntlrDeepColorSet(struct HdmiCntlr *cntlr, enum HdmiDeepColor color);
int32_t HdmiCntlrDeepColorGet(struct HdmiCntlr *cntlr, enum HdmiDeepColor *color);
int32_t HdmiCntlrSetVideoAttribute(struct HdmiCntlr *cntlr, struct HdmiVideoAttr *attr);
int32_t HdmiCntlrSetAudioAttribute(struct HdmiCntlr *cntlr, struct HdmiAudioAttr *attr);
int32_t HdmiCntlrSetHdrAttribute(struct HdmiCntlr *cntlr, struct HdmiHdrAttr *attr);
int32_t HdmiCntlrInfoframeGet(struct HdmiCntlr *cntlr, enum HdmiPacketType type, union HdmiInfoframeInfo *frame);
int32_t HdmiCntlrInfoframeSet(struct HdmiCntlr *cntlr, enum HdmiPacketType type, union HdmiInfoframeInfo *frame);
void HdmiCntlrClose(struct HdmiCntlr *cntlr);
bool HdmiHpdStatusDelayGet(struct HdmiCntlr *cntlr);
bool HdmiHpdStatusGet(struct HdmiCntlr *cntlr);
int32_t HdmiEventHandle(struct HdmiCntlr *cntlr, enum HdmiEventType event, void *datat);
int32_t HdmiEventMsgHandleDefault(struct PlatformQueue *queue, struct PlatformMsg *msg);
bool HdmiEdidSupportFrl(struct HdmiDevice *hdmi);
uint8_t HdmiEdidGetMaxFrlRate(struct HdmiDevice *hdmi);
bool HdmiEdidScdcSupport(struct HdmiDevice *hdmi);
int32_t HdmiCntlrAllocDev(struct HdmiCntlr *cntlr);
void HdmiCntlrFreeDev(struct HdmiCntlr *cntlr);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* HDMI_CORE_H */
+77
View File
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef HDMI_DDC_H
#define HDMI_DDC_H
#include "hdf_base.h"
#include "osal_mutex.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
/*
* DDC(Display Data Channel)
* The DDC channel is used by an HDMI Source to determine the capabilities and characteristics of
* the Sink by reading the E-EDID data structure.
* The DDC is also uesd to exchange point-to-point dynamic data between the Source and the Sink
* using a new DDC address for the HDMI Status and Control Data Channel(SCDC).
* In addition, The DDC is also uesd for HDCP to exchange key selection vector and other information.
*/
#define HDMI_DDC_EDID_DEV_ADDRESS 0xA0
#define HDMI_DDC_SCDC_DEV_ADDRESS 0xA8
#define HDMI_DDC_HDCP_DEV_ADDRESS 0x74
enum HdmiDdcDeviceType {
HDMI_DDC_DEV_EDID = 0,
HDMI_DDC_DEV_SCDC = 1,
HDMI_DDC_DEV_HDCP = 2,
HDMI_DDC_DEV_BUTT,
};
enum HdmiDdcMode {
HDMI_DDC_MODE_READ_SINGLE_NO_ACK = 0,
HDMI_DDC_MODE_READ_SINGLE_ACK = 1,
HDMI_DDC_MODE_READ_MUTIL_NO_ACK = 2,
HDMI_DDC_MODE_READ_MUTIL_ACK = 3,
HDMI_DDC_MODE_READ_SEGMENT_NO_ACK = 4,
HDMI_DDC_MODE_READ_SEGMENT_ACK = 5,
HDMI_DDC_MODE_WRITE_MUTIL_NO_ACK = 6,
HDMI_DDC_MODE_WRITE_MUTIL_ACK = 7,
HDMI_DDC_MODE_BUTT,
};
struct HdmiDdcCfg {
enum HdmiDdcDeviceType type;
enum HdmiDdcMode mode;
bool readFlag;
uint32_t devAddr;
uint8_t offset;
uint8_t segment; /* see VESA spec. 1 segment is 256 bytes. */
uint32_t dataLen;
uint8_t *data;
};
struct HdmiDdc {
struct OsalMutex ddcMutex;
bool init;
void *priv;
};
int32_t HdmiDdcTransfer(struct HdmiDdc *ddc, struct HdmiDdcCfg *cfg);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* HDMI_DDC_H */
+162
View File
@@ -0,0 +1,162 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef HDMI_DFM_H
#define HDMI_DFM_H
#include "hdmi_if.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
/*
* DFM(Data Flow Metering).
* During data transmission in FRL mode, there is a lot of bandwidth redundancy (blanking period) or slight bandwidth
* insufficiency (active video). In order for the link to tolerate these fluctuations, source and sink need to use
* buffers. To limit the size of the buffer required, the protocol adds the Data Flow Metering requirement.
*/
#define HDMI_DFM_FRL_CHAR_NUM_PER_CB 502
#define HDMI_DFM_RS_NUM_PER_CB 8
/* A FRL Character Block(CB) contains 502 FRL Characters and 8 RS check characters. */
#define HDMI_DFM_CHAR_NUM_PER_CB (HDMI_DFM_FRL_CHAR_NUM_PER_CB + HDMI_DFM_RS_NUM_PER_CB)
/*
* A FRL Super Block(SB) contains four FRL Character Blocks.
* Each FRL Super Block is preceded by a group of three or four Start Super Blocks (SSB) or a group of three or
* four Scrambler Reset (SR) characters.
*/
#define HDMI_DFM_FRL_CB_NUM_PER_SB 4
#define HDMI_DFM_FRL_SB_LEN(lane) (HDMI_DFM_FRL_CB_NUM_PER_SB * HDMI_DFM_CHAR_NUM_PER_CB + lane)
#define HDMI_DFM_FRL_PIXELCLK_TOLERANCE 5 /* 0.50% */
#define HDMI_DFM_FRL_BITRATE_TOLERANCE 3 /* 300 */
#define HDMI_DFM_FRL_AUDIOCLK_TOLERANCE 1
#define HDMI_DFM_MAGNIFICATION_8 8
#define HDMI_DFM_FRL_MAX_TB_BORROW 400
#define HDMI_DFM_RATE_MAGNIFICATION 100000
#define HDMI_DFM_OVERHEAD_SIZE 300
#define HDMI_AUDIO_CHANNEL_ALLOC_TYPE1 1
#define HDMI_AUDIO_CHANNEL_ALLOC_TYPE2 2
#define HDMI_AUDIO_CHANNEL_ALLOC_TYPE3 3
/*
* Packets per sample.
* This is the number of audio packets required to carry each sample.
* x100.
*/
#define HDMI_AUDIO_AP_SIZE_25 25
#define HDMI_AUDIO_AP_SIZE_100 100
#define HDMI_AUDIO_AP_SIZE_200 200
#define HDMI_AUDIO_AP_SIZE_300 300
#define HDMI_AUDIO_AP_SIZE_400 400
enum HdmiAudioPacketType {
HDMI_AUDIO_SAMPLE_PACKET = 0x02,
HDMI_ONE_BIT_AUDIO_SAMPLE_PACKET = 0x07,
HDMI_DTS_AUDIO_PACKET = 0x08,
HDMI_HBR_AUDIO_PACKET = 0x09,
HDMI_AUDIO_3D_SAMPLE_PACKET = 0x0B,
HDMI_ONE_BIT_AUDIO_3D_SAMPLE_PACKET = 0x0C,
HDMI_MULTI_STREAM_AUDIO_SAMPLE_PACKET = 0x0E,
HDMI_ONE_BIT_MULTI_STREAM_AUDIO_SAMPLE_PACKET = 0x0F,
};
enum HdmiDfmPixelFormatMode {
HDMI_DFM_PIXEL_FORMAT_MODE_0 = 0,
HDMI_DFM_PIXEL_FORMAT_MODE_1,
HDMI_DFM_PIXEL_FORMAT_MODE_2,
HDMI_DFM_PIXEL_FORMAT_MODE_3
};
struct HdmiDfmInfo {
bool audioSupport;
bool videoSupport;
bool uncompressSupport;
bool isExtraMode;
bool canbeTrans;
uint32_t htotal;
uint32_t vtotal;
uint32_t bpp; /* Bits per Pixel */
uint32_t cFrlSb; /* Total FRL Characters Per SuperBlock(include SSB/SR) */
uint32_t overheadSb;
uint32_t overheadRs;
uint32_t overheadMap;
uint32_t overheadMin;
uint32_t overheadMax;
uint32_t lineMinTime; /* minimum Video Line period */
uint32_t lineMaxTime; /* maximum Video Line period */
uint32_t audioAp; /* the number of audio packets required to carry each sample */
uint32_t audioRap; /* Average Audio Related Packet Rate */
uint32_t avgAudioPacketsPerLine; /* Average Required Packets per line */
uint32_t audioPacketsLine; /* Packets per Hblank that must be supportable. */
uint32_t hblankAudioMin; /* */
uint32_t cFrlFree;
uint32_t cFrlRcMargin;
uint32_t cFrlRcSavings;
uint32_t activeBytesPerLine; /* Video Bytes per line */
uint32_t activeTbPerLine; /* Required Characters to carry Active Video per line */
uint32_t hblankTbPerLine; /* Required Characters to carry H-Blank Video per line */
uint32_t activeTimeRef;
uint32_t blankTimeRef;
uint32_t activeTimeMin;
uint32_t blankTimeMin;
int32_t tBorrow;
int32_t tbBorrow;
uint32_t cFrlActualPayload;
uint32_t utilization;
int32_t margin;
uint32_t avgTbRate;
uint64_t pixelClk;
uint64_t maxPixelClk; /* maximum legal pixel rate */
uint64_t minPixelClk; /* minimum legal pixel rate */
uint64_t maxBitRate; /* FRL max bit rate */
uint64_t minBitRate; /* FRL min bit rate */
uint64_t maxFrlCharRate; /* max FRL Character Rate */
uint64_t minFrlCharRate; /* min FRL Character Rate */
uint32_t maxFrlCharsPerLine; /* max FRL Characters per line Period */
uint32_t minFrlCharsPerLine; /* min FRL Characters per line Period */
};
struct HdmiDfmParam {
uint32_t hactive;
uint32_t vactive;
uint32_t hblank;
uint32_t vblank;
uint32_t hsync;
uint32_t hback;
uint32_t hfront;
uint32_t vsync;
uint32_t vback;
uint32_t vfront;
uint32_t vfreq;
uint32_t colorDepth;
uint32_t pixelFormat; /* 1:420, 2:422, 3:RGB444 */
uint32_t laneNum;
uint32_t bitRate;
uint32_t audioRate;
uint32_t packetType;
uint32_t layout;
uint32_t acat;
};
uint32_t HdmiDfmGetPixelFormat(enum HdmiColorSpace colorSpace);
void HdmiDfmFillParam(struct HdmiDfmParam *param, struct HdmiVideoDefInfo *videoInfo,
struct HdmiAudioAttr *audioAttr, enum HdmiColorSpace colorSpace, enum HdmiDeepColor deepColor);
bool HdmiDfmFormatSupport(struct HdmiDfmParam *param);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* HDMI_DFM_H */
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef HDMI_DISPATCH_H
#define HDMI_DISPATCH_H
#include "hdf_base.h"
#ifndef __USER__
#include "devsvc_manager_clnt.h"
#endif
#ifdef __USER__
#include "hdf_io_service_if.h"
#endif
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
#ifndef __USER__
int32_t HdmiIoDispatch(struct HdfDeviceIoClient *client, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply);
#endif
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* HDMI_NCTS_H */
+635
View File
@@ -0,0 +1,635 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef HDMI_EDID_H
#define HDMI_EDID_H
#include "hdf_base.h"
#include "hdmi_ddc.h"
#include "hdmi_if.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
/* (EDID)Extended Display Identification Data */
#define HDMI_EDID_SINGLE_BLOCK_SIZE 128
#define HDMI_EDID_MAX_BLOCK_NUM 4
#define HDMI_EDID_TOTAL_SIZE (HDMI_EDID_SINGLE_BLOCK_SIZE * HDMI_EDID_MAX_BLOCK_NUM)
#define HDMI_EDID_MAX_VIC_COUNT 128
#define HDMI_EDID_BIT0_MARK 0x01
#define HDMI_EDID_BIT1_MARK 0x02
#define HDMI_EDID_BIT2_MARK 0x04
#define HDMI_EDID_BIT3_MARK 0x08
#define HDMI_EDID_BIT4_MARK 0x10
#define HDMI_EDID_BIT5_MARK 0x20
#define HDMI_EDID_BIT6_MARK 0x40
#define HDMI_EDID_BIT7_MARK 0x80
#define HDMI_EDID_UPPER_NIBBLE_MARK 0xf0
#define HDMI_EDID_LOWER_NIBBLE_MARK 0x0f
#define HDMI_EDID_BITS_OF_ONE_BYTE 8
#define HDMI_EDID_ONE_BYTE_SHIFT 8
#define HDMI_EDID_6_BITS_SHIFT 6
#define HDMI_EDID_NIBBLE_SHIFT 4
#define HDMI_EDID_2_BITS_SHIFT 2
#define HDMI_EDID_CHECK_SUM_MARK 0xff
/* edid header */
#define HDMI_EDID_BLOCK_HEADER_FIELD_LEN 8
/* edid vendor/product info */
#define HDMI_EDID_MANUFACRURER_NAME_FIELD_LEN 2
#define HDMI_EDID_MANUFACRURER_NAME_MAX_LEN 4
#define HDMI_EDID_MANUFACRURER_NAME_CHAR_MARK 0x1F /* 5 bits */
#define HDMI_EDID_MANUFACRURER_NAME_CHAR_SHIFT 5
#define HDMI_EDID_MANUFACRURER_NAME_LOW_INVALID 0
#define HDMI_EDID_MANUFACRURER_NAME_HIGH_INVALID 27
#define HDMI_EDID_MANUFACRURER_NAME_SHIFT 8
#define HDMI_EDID_PRODUCT_CODE_FIELD_LEN 2
#define HDMI_EDID_PRODUCT_CODE_SHIFT 8
#define HDMI_EDID_SERIAL_NUMBER_FIELD_LEN 4
#define HDMI_EDID_SERIAL_NUMBER_SHIFT 8
#define HDMI_EDID_WEEK_LOW_VALID 1
#define HDMI_EDID_WEEK_HIGH_VALID 53
#define HDMI_EDID_YEAR_VALID 0xFF
#define HDMI_EDID_YEAR_BASE 1990
struct HdmiEdidVendorInfo {
char mfrName[HDMI_EDID_MANUFACRURER_NAME_MAX_LEN];
uint16_t productCode;
uint32_t serialNumber;
uint8_t week;
uint8_t year;
};
#define HDMI_EDID_VERSION_NUM 1
#define HDMI_EDID_REVISION_NUM 3
/* edid version info */
struct HdmiEdidVersionInfo {
uint8_t version;
uint8_t revision;
};
/* edid basic display parameters and features */
struct HdmiEdidBasicDispParamInfo {
uint8_t width; /* unit: cm */
uint8_t height; /* unit: cm */
};
/* edid color characteristics */
#define HDMI_EDID_COLOR_LOW_BITS_MARK 0x03
#define HDMI_EDID_COLOR_RED_X_LOW_OFFSET 6
#define HDMI_EDID_COLOR_RED_Y_LOW_OFFSET 4
#define HDMI_EDID_COLOR_GREEN_X_LOW_OFFSET 2
#define HDMI_EDID_COLOR_BLUE_X_LOW_OFFSET 6
#define HDMI_EDID_COLOR_BLUE_Y_LOW_OFFSET 4
#define HDMI_EDID_COLOR_WHITE_X_LOW_OFFSET 2
#define HDMI_EDID_COLOR_HIGH_OFFSET 2
struct HdmiEdidColorInfo {
uint16_t redX;
uint16_t redY;
uint16_t greenX;
uint16_t greenY;
uint16_t blueX;
uint16_t blueY;
uint16_t whiteX;
uint16_t whiteY;
};
/* edid established timings */
#define HDMI_EDID_ESTABLISHED_TIMINGS_FIELD_LEN 3
enum HdmiEdidEstablishTiming {
HDMI_EDID_ESTABLISHED_TIMING_VESA_800X600_60 = 0,
HDMI_EDID_ESTABLISHED_TIMING_VESA_800X600_56 = 1,
HDMI_EDID_ESTABLISHED_TIMING_VESA_640X480_75 = 2,
HDMI_EDID_ESTABLISHED_TIMING_VESA_640X480_72 = 3,
HDMI_EDID_ESTABLISHED_TIMING_640X480_67 = 4,
HDMI_EDID_ESTABLISHED_TIMING_VGA_640X480_60 = 5,
HDMI_EDID_ESTABLISHED_TIMING_XGA_720X400_88 = 6,
HDMI_EDID_ESTABLISHED_TIMING_VGA_720X400_70 = 7,
HDMI_EDID_ESTABLISHED_TIMING_VESA_1280X1024_75 = 8,
HDMI_EDID_ESTABLISHED_TIMING_VESA_1024X768_75 = 9,
HDMI_EDID_ESTABLISHED_TIMING_VESA_1024X768_70 = 10,
HDMI_EDID_ESTABLISHED_TIMING_VESA_1024X768_60 = 11,
HDMI_EDID_ESTABLISHED_TIMING_1024X768_87 = 12,
HDMI_EDID_ESTABLISHED_TIMING_832X624_75 = 13,
HDMI_EDID_ESTABLISHED_TIMING_VESA_800X600_75 = 14,
HDMI_EDID_ESTABLISHED_TIMING_VESA_800X600_72 = 15,
HDMI_EDID_ESTABLISHED_TIMING_VESA_1152X870_75 = 16,
HDMI_EDID_ESTABLISHED_TIMING_BUTT,
};
struct HdmiEdidEstablishedTimingsInfo {
uint32_t estTimingsNum;
uint32_t estTimings[HDMI_EDID_ESTABLISHED_TIMING_BUTT];
};
/* edid standard timing */
#define HDMI_EDID_STANDARD_TIMING_FIELD_LEN 16
#define HDMI_EDID_STANDARD_TIMING_COUNT 8
#define HDMI_EDID_PER_STANDARD_TIMING_BYTE_NUM 2
#define HDMI_EDID_STANDARD_TIMING_UNUSED_FLAG 0x01
#define HDMI_EDID_STANDARD_TIMING_HORIZ_PIXEL_BASE 31
#define HDMI_EDID_STANDARD_TIMING_HORIZ_PIXEL_FACTOR 8
#define HDMI_EDID_STANDARD_TIMING_REFRESH_RATE_BASE 60
#define HDMI_EDID_STANDARD_TIMING_REFRESH_RATE_MARK 0x3F
#define HDMI_EDID_STANDARD_TIMING_ASPECT_RATE_MARK 0xC0
#define HDMI_EDID_STANDARD_TIMING_ASPECT_RATE_SHIFT 6
enum HdmiEdidStdTimingAspectRate {
HDMI_EDID_STANDARD_TIMING_ASPECT_RATE_16_10 = 0,
HDMI_EDID_STANDARD_TIMING_ASPECT_RATE_5_4 = 1,
HDMI_EDID_STANDARD_TIMING_ASPECT_RATE_4_3 = 2,
HDMI_EDID_STANDARD_TIMING_ASPECT_RATE_16_9 = 3,
};
struct HdmiEdidStdTimingInfo {
uint32_t horizPixel;
uint32_t vertPixel;
uint32_t refreshRate;
};
/* edid detailed timing descriptor */
#define HDMI_EDID_DETAILED_TIMING_DESCRIPTOR_FIELD_LEN 18
#define HDMI_EDID_DETAILED_TIMING_PIXEL_CLK_FIELD_LEN 2
#define HDMI_EDID_DETAILED_TIMING_PIXEL_CLK_KHZ_FACTOR 10
#define HDMI_EDID_DETAILED_TIMING_UPPER_4BITS_MARK 0xF0
#define HDMI_EDID_DETAILED_TIMING_LOWER_4BITS_MARK 0x0F
#define HDMI_EDID_DETAILED_TIMING_HS_OFFSET_MARK 0xC0
#define HDMI_EDID_DETAILED_TIMING_HS_PULSE_WIDTH_MARK 0x30
#define HDMI_EDID_DETAILED_TIMING_VS_OFFSET_MARK 0x0C
#define HDMI_EDID_DETAILED_TIMING_VS_PULSE_WIDTH_MARK 0x03
#define HDMI_EDID_DETAILED_TIMING_STEREO_MARK 0x60
#define HDMI_EDID_DETAILED_TIMING_STEREO_SEQUENTIAL_R 0x02
#define HDMI_EDID_DETAILED_TIMING_STEREO_SEQUENTIAL_L 0x04
#define HDMI_EDID_DETAILED_TIMING_STEREO_INTERLEAVED_2R 0x03
#define HDMI_EDID_DETAILED_TIMING_STEREO_INTERLEAVED_2L 0x05
#define HDMI_EDID_DETAILED_TIMING_STEREO_INTERLEAVED_4 0x06
#define HDMI_EDID_DETAILED_TIMING_STEREO_INTERLEAVED_SBS 0x07
#define HDMI_EDID_DETAILED_TIMING_SYNC_SIGNAL_TYPE_MARK 0x0E
#define HDMI_EDID_DETAILED_TIMING_SYNC_DCS_WS_0 0x00
#define HDMI_EDID_DETAILED_TIMING_SYNC_DCS_WS_1 0x01
#define HDMI_EDID_DETAILED_TIMING_SYNC_DCS_DS_2 0x02
#define HDMI_EDID_DETAILED_TIMING_SYNC_DCS_DS_3 0x03
#define HDMI_EDID_DETAILED_TIMING_SYNC_DSS_VN_HN_4 0x04
#define HDMI_EDID_DETAILED_TIMING_SYNC_DSS_VN_HP_5 0x05
#define HDMI_EDID_DETAILED_TIMING_SYNC_DSS_VP_HN_6 0x06
#define HDMI_EDID_DETAILED_TIMING_SYNC_DSS_VP_HP_7 0x07
#define HDMI_EDID_MAX_DETAILED_TIMING_COUNT 10
struct HdmiEdidDetailedTimingBlockInfo {
uint8_t pixelClk[HDMI_EDID_DETAILED_TIMING_PIXEL_CLK_FIELD_LEN];
uint8_t hActive;
uint8_t hBlanking;
uint8_t hActiveBlanking;
uint8_t vActive;
uint8_t vBlanking;
uint8_t vActiveBlanking;
uint8_t hSyncOffset;
uint8_t hSyncPulseWidth;
uint8_t vsOffesetPulseWidth;
uint8_t hsOffsetVsOffset;
uint8_t hImageSize;
uint8_t vImageSize;
uint8_t hvImageSize;
uint8_t hBorder;
uint8_t vBorder;
uint8_t flags;
};
struct HdmiEdidPreferredTimingInfo {
uint32_t pixelClk; /* unit: KHz */
uint32_t hActive; /* horizontal active area */
uint32_t hBackBlank; /* horizontal back blank */
uint32_t hFrontBlank; /* horizontal front blank */
uint32_t hSyncPluseWidth; /* horizontal sync pluse width */
uint32_t vActive; /* vertical active area */
uint32_t vBackBlank; /* vertical back blank */
uint32_t vFrontBlank; /* vertical front blank */
uint32_t vSyncPluseWidth; /* vertical sync pluse width */
uint32_t imageWidth; /* image width */
uint32_t imageHeight; /* image height */
bool interlaceFlag; /* interlace flag */
bool idv; /* flag of data valid signal is needed flip */
bool ihs; /* flag of horizontal sync pulse is needed flip */
bool ivs; /* flag of vertical sync pulse is needed flip */
};
/* edid monitor descriptor */
#define HDMI_EDID_MONITOR_FLAGS_FIELD_LEN 3
#define HDMI_EDID_MONITOR_DATA_FIELD_LEN 13
#define HDMI_EDID_MAX_SINK_NAME_COUNT 14
enum HdmiEdidMonitorDataType {
HDMI_EDID_MONITOR_DATA_NAME = 0xFC,
HDMI_EDID_MONITOR_DATA_RANGE_LIMIT = 0xFD,
HDMI_EDID_MONITOR_DATA_STRING = 0xFE,
HDMI_EDID_MONITOR_DATA_SERIAL_NUMBER = 0xFF,
};
struct HdmiEdidMonitorBlockInfo {
uint8_t flags[HDMI_EDID_MONITOR_FLAGS_FIELD_LEN];
uint8_t dataTag;
uint8_t flag;
uint8_t data[HDMI_EDID_MONITOR_DATA_FIELD_LEN];
};
/* edid extension flag and checksum */
#define HDMI_EDID_EXTENSION_BLOCK_ADDR 0x7E
#define HDMI_EDID_CHECKSUM_ADDR 0x7F
struct HdmiEdidFirstBlockInfo {
uint8_t header[HDMI_EDID_BLOCK_HEADER_FIELD_LEN];
uint8_t vendorName[HDMI_EDID_MANUFACRURER_NAME_FIELD_LEN];
uint8_t productCode[HDMI_EDID_PRODUCT_CODE_FIELD_LEN];
uint8_t serialNumber[HDMI_EDID_SERIAL_NUMBER_FIELD_LEN];
uint8_t week; /*
* The designated values for this field range from 1 to 53. If this field is unused, the value
* should be set to 0. If the next field is used for Model Year, then 0xFF should be set.
*/
uint8_t year; /* This value is determined by the actual year of production minus 1990. */
uint8_t version;
uint8_t revision;
uint8_t videoInput;
uint8_t width; /* unit: cm */
uint8_t height; /* unit: cm */
uint8_t gamma; /* Display Transfer Characteristics */
uint8_t features;
uint8_t redGreenLow;
uint8_t blueWhiteLow;
uint8_t redX;
uint8_t redY;
uint8_t greenX;
uint8_t greenY;
uint8_t blueX;
uint8_t blueY;
uint8_t whiteX;
uint8_t whiteY;
uint8_t estTimings[HDMI_EDID_ESTABLISHED_TIMINGS_FIELD_LEN];
uint8_t stdTiming[HDMI_EDID_STANDARD_TIMING_FIELD_LEN];
uint8_t detailedTiming1[HDMI_EDID_DETAILED_TIMING_DESCRIPTOR_FIELD_LEN];
uint8_t detailedTiming2[HDMI_EDID_DETAILED_TIMING_DESCRIPTOR_FIELD_LEN];
uint8_t detailedTiming3[HDMI_EDID_DETAILED_TIMING_DESCRIPTOR_FIELD_LEN];
uint8_t detailedTiming4[HDMI_EDID_DETAILED_TIMING_DESCRIPTOR_FIELD_LEN];
uint8_t extensionFlag;
uint8_t checksum;
};
/* edid extension block */
#define HDMI_EDID_CTA_EXTENSION_TAG 0x02
#define HDMI_EDID_CTA_EXTENSION3_REVISION 0x03
#define HDMI_EDID_EXTENSION_DATA_BLOCK_LEN_MARK 0x1F
#define HDMI_EDID_EXTENSION_DATA_BLOCK_TAG_CODE_MARK 0xE0
#define HDMI_EDID_EXTENSION_DATA_BLOCK_TAG_CODE_SHIFT 5
#define HDMI_EDID_EXTENSION_BLOCK_OFFSET 4
#define HDMI_EDID_EXTENSION_D_INVALID_MIN_VAL 4
enum HdmiEdidExtDataBlockType {
HDMI_EDID_NULL_DATA_BLOCK = 0,
HDMI_EDID_AUDIO_DATA_BLOCK = 1,
HDMI_EDID_VIDEO_DATA_BLOCK = 2,
HDMI_EDID_VENDOR_SPECIFIC_DATA_BLOCK = 3,
HDMI_EDID_SPEAKER_ALLOCATION_DATA_BLOCK = 4,
HDMI_EDID_VESA_DTC_DATA_BLOCK = 5, /* VESA Display Transfer Characteristic Data Block */
HDMI_EDID_USE_EXT_DATA_BLOCK = 7, /* Use Extended Tag */
};
struct HdmiEdidColorSpace {
bool rgb444;
bool ycbcr422;
bool ycbcr444;
bool ycbcr420;
};
/* edid extension block: Audio Data Block */
#define HDMI_EDID_EXTENSION_SHORT_AUDIO_DESCRIPTOR_LEN 3
#define HDMI_EDID_EXTENSION_MAX_SHORT_AUDIO_DESCRIPTOR_NUM 10
#define HDMI_EDID_EXTENSION_AUDIO_FORMAT_CODE_MARK 0x78
#define HDMI_EDID_EXTENSION_AUDIO_FORMAT_CODE_SHIFT 3
#define HDMI_EDID_EXTENSION_AUDIO_MAX_CHANNEL_MARK 0x07
#define HDMI_EDID_EXTENSION_AUDIO_MAX_SAMPLE_RATE_NUM 8
#define HDMI_EDID_EXTENSION_AUDIO_MAX_BIT_DEPTH_NUM 6
#define HDMI_EDID_EXTENSION_AUDIO_BIT_RATE_FACTOR 8
#define HDMI_EDID_EXTENSION_AUDIO_CAP_COUNT 16
struct HdmiEdidAudioInfo {
enum HdmiAudioCodingType formatCode;
uint32_t sampleRateNum;
enum HdmiSampleRate sampleRate[HDMI_EDID_EXTENSION_AUDIO_MAX_SAMPLE_RATE_NUM];
uint32_t bitDepthNum;
enum HdmiAudioBitDepth bitDepth[HDMI_EDID_EXTENSION_AUDIO_MAX_BIT_DEPTH_NUM];
uint8_t channels;
uint32_t maxBitRate; /* unit: KHz */
};
/* edid extension block: Video Data Block */
#define HDMI_EDID_EXTENSION_VIC_NATIVE_MAX 64
#define HDMI_EDID_EXTENSION_VIC_LOWER7_MARK 0x7F
#define HDMI_EDID_EXTENSION_MAX_VIC_COUNT 128
#define HDMI_EDID_EXTENSION_VIC_INVALID_LOW 128
#define HDMI_EDID_EXTENSION_VIC_INVALID_HIGH 192
/*
* Each supported Video Format is represented by a Short Video Descriptor (SVD) containing
* a Video Identification Code (VIC) and, in the case of VICs 1 through 64, a Native Video Format indicator.
*/
struct HdmiEdidVideoInfo {
uint32_t vicNum;
uint32_t vic[HDMI_EDID_EXTENSION_MAX_VIC_COUNT];
uint32_t nativeFormat;
};
/* edid extension block: (VSDB)Vendor-Specific Data Block */
#define HDMI_EDID_EXTENSION_VSDB_LEN 3
#define HDMI_EDID_EXTENSION_VSDB_IEEE_1ST 0x03
#define HDMI_EDID_EXTENSION_VSDB_IEEE_2ND 0x0C
#define HDMI_EDID_EXTENSION_VSDB_IEEE_3RD 0x00
#define HDMI_EDID_EXTENSION_VSDB_CEC_INVALID_ADDR 0xF
#define HDMI_EDID_EXTENSION_MAX_HDMI14_TMDS_RATE 340 /* unit: Mcsc */
#define HDMI_EDID_EXTENSION_TMDS_FACTOR 5 /* unit: MHz */
#define HDMI_EDID_EXTENSION_VSDB_3D_LEN_MARK 0x1F
#define HDMI_EDID_EXTENSION_VSDB_VIC_LEN_MARK 0xE0
#define HDMI_EDID_EXTENSION_VSDB_VIC_LEN_SHIFT 5
#define HDMI_EDID_EXTENSION_VSDB_3D_MULTI_PRESENT_MARK 0x60
#define HDMI_EDID_EXTENSION_VSDB_3D_MULTI_PRESENT_SHIFT 5
#define HDMI_EDID_EXTENSION_VSDB_3D_STR_INVALID_MARK 0x03
struct HdmiEdidVsdbCecAddr {
bool addrValid;
uint8_t phyAddrA;
uint8_t phyAddrB;
uint8_t phyAddrC;
uint8_t phyAddrD;
};
struct HdmiEdidDeepColor {
bool dcY444;
bool dc30bit;
bool dc36bit;
bool dc48bit;
};
struct HdmiEdidExtVsdbInfo {
struct HdmiEdidVsdbCecAddr cecAddr;
struct HdmiEdidDeepColor deepColor;
bool supportAi;
bool supportDviDual;
bool latencyFieldsPresent;
bool iLatencyFieldsPresent;
bool hdmiVideoPresent;
uint8_t videoLatency;
uint8_t audioLatency;
uint8_t interlacedVideoLatency;
uint8_t interlacedAudioLatency;
bool _3dPresent;
bool _3dMultiPresent;
bool support3dType[HDMI_VS_VIDEO_3D_BUTT];
};
/* edid extension block: (HF-VSDB)HDMI Forum Vendor-Specific Data Block */
#define HDMI_EDID_EXTENSION_HFVSDB_IEEE_1ST 0xD8
#define HDMI_EDID_EXTENSION_HFVSDB_IEEE_2ND 0x5D
#define HDMI_EDID_EXTENSION_HFVSDB_IEEE_3RD 0xC4
#define HDMI_EDID_EXTENSION_HFVSDB_VERSION 0x01
#define HDMI_EDID_EXTENSION_HFVSDB_MIN_INVALID_LEN 7
#define HDMI_EDID_EXTENSION_HFVSDB_MAX_INVALID_LEN 31
/* deep color Y420(4:2:0) */
struct HdmiEdidExtHfVsdbDeepColor {
bool dc30bit;
bool dc36bit;
bool dc48bit;
};
/* dsc(Display Stream Compression ) */
struct HdmiEdidExtHfVsdbDscInfo {
bool dsc1p2;
bool dscNative420;
bool dscAllBpp;
bool dsc10bpc;
bool dsc20bpc;
bool dsc16bpc;
uint8_t dscMaxSlices;
uint8_t dscMaxFrlRate;
uint8_t dscTotalChunkKBytes;
};
struct HdmiEdidExtHfVsdbInfo {
bool scdcPresent;
bool rrCapable; /* read request cap. */
bool lte340McscScramble;
bool independentView;
bool dualView;
bool _3dOsdDisparity;
struct HdmiEdidExtHfVsdbDeepColor dc;
/* hdmi 2.1 */
uint8_t maxFrlRate;
bool fapaStartLocation;
bool allm;
bool fva;
bool cnmVrr;
bool cinemaVrr;
bool mDelta;
uint8_t vrrMin;
uint16_t vrrMax;
struct HdmiEdidExtHfVsdbDscInfo dscInfo;
};
/* edid extension block: Speaker Allocation Data Block */
#define HDMI_EDID_EXTENSION_SADB_MIN_INVALID_LEN 2
enum HdmiEdidAudioSpeaker {
HDMI_EDID_AUDIO_SPEAKER_FL_FR = 0,
HDMI_EDID_AUDIO_SPEAKER_LFE = 1,
HDMI_EDID_AUDIO_SPEAKER_FC = 2,
HDMI_EDID_AUDIO_SPEAKER_BL_BR = 3,
HDMI_EDID_AUDIO_SPEAKER_BC = 4,
HDMI_EDID_AUDIO_SPEAKER_FLC_FRC = 5,
HDMI_EDID_AUDIO_SPEAKER_RLC_RRC = 6,
HDMI_EDID_AUDIO_SPEAKER_FLW_FRW = 7,
HDMI_EDID_AUDIO_SPEAKER_TPFL_TPFH = 8,
HDMI_EDID_AUDIO_SPEAKER_TPC = 9,
HDMI_EDID_AUDIO_SPEAKER_TPFC = 10,
HDMI_EDID_AUDIO_SPEAKER_BUTT,
};
/*
* If the Tag Code is 7 (Use Extended Tag) then the second byte of the data block contains the Extended
* Tag Code, which indicates the actual type of the data block.
*/
enum HdmiEdidExtExtenedDataBlockType {
HDMI_EDID_EXT_VCDB = 0, /* Video Capability Data Block */
HDMI_EDID_EXT_VSVDB = 1, /* Vendor-Specific Video Data Block */
HDMI_EDID_EXT_VESA_DDDB = 2, /* VESA Display Device Data Block */
HDMI_EDID_EXT_VESA_VTBE = 3, /* VESA Video Timing Block Extension */
HDMI_EDID_EXT_CDB = 5, /* Colorimetry Data Block */
HDMI_EDID_EXT_HDR_SMDB = 6, /* HDR Static Metadata Data Block */
HDMI_EDID_EXT_HDR_DMDB = 7, /* HDR Dynamic Metadata Data Block */
HDMI_EDID_EXT_VFPDB = 13, /* Video Format Preference Data Block */
HDMI_EDID_EXT_YCBCR420_VDB = 14, /* YCBCR 4:2:0 Video Data Block */
HDMI_EDID_EXT_YCBCR420_CMDB = 15, /* YCBCR 4:2:0 Capability Map Data Block */
HDMI_EDID_EXT_VSADB = 17, /* Vendor-Specific Audio Data Block */
HDMI_EDID_EXT_RCDB = 19, /* Room Configuration Data Block */
HDMI_EDID_EXT_SLDB = 20, /* Speaker Location Data Block */
HDMI_EDID_EXT_INFOFRAME_DB = 32, /* InfoFrame Data Block (includes one or more Short InfoFrame Descriptors) */
HDMI_EDID_EXT_BUTT,
};
/* edid extension block: Colorimetry Data Block */
#define HDMI_EDID_CDB_LEN 3
struct HdmiEdidColorimetry {
bool xvYcc601;
bool xvYcc709;
bool sYcc601;
bool opYcc601;
bool opRgb;
bool bt2020cYcc;
bool bt2020Ycc;
bool bt2020Rgb;
bool dciP3;
uint8_t md;
};
/* edid extension block: Vendor-Specific Video Data Block */
#define HDMI_EDID_VSVDB_DOLBY_OUI 0x00D046
#define HDMI_EDID_VSVDB_DOLBY_VERSION_0 0x00
#define HDMI_EDID_VSVDB_DOLBY_VERSION_1 0x01
#define HDMI_EDID_VSVDB_DOLBY_VERSION_0_LEN 27
#define HDMI_EDID_VSVDB_DOLBY_VERSION_1_LEN 14
#define HDMI_EDID_VSVDB_DOLBY_LOWER_2BIT_MARK 0x03
#define HDMI_EDID_VSVDB_DOLBY_LOWER_3BIT_MARK 0x07
#define HDMI_EDID_VSVDB_DOLBY_LOWER_7BIT_MARK 0x7F
#define HDMI_EDID_VSVDB_DOLBY_VERSION_MARK 0xE0
#define HDMI_EDID_VSVDB_DOLBY_VERSION_SHIFT 5
#define HDMI_EDID_VSVDB_DOLBY_DM_VER_MARK 0x1C
#define HDMI_EDID_VSVDB_DOLBY_DM_VER_SHIFT 2
struct HdmiEdidVsvdbDolbyCap {
uint32_t oui;
uint8_t version;
bool yuv422;
bool b2160p60; /* capable of processing a max timing 3840X2160p60. */
bool globalDimming;
uint16_t redX;
uint16_t redY;
uint16_t greenX;
uint16_t greenY;
uint16_t blueX;
uint16_t blueY;
uint16_t whiteX; /* only version0 support */
uint16_t whiteY; /* only version0 support */
uint16_t minLuminance;
uint16_t maxLuminance;
uint8_t dMajorVer; /* only version0 support */
uint8_t dMinorVer; /* only version0 support */
bool colorimetry; /* only version1 support */
uint8_t dmVer; /* only version1 support */
};
/* edid extension block: Video Capability Data Block */
#define HDMI_EDID_VCDB_LEN 2
struct HdmiEdidVideoCapability {
bool qy; /* Quantization Range(Applies to YCC only) */
bool qs; /* Quantization Range Selectable(Applies to RGB only) */
};
/* edid extension block: HDR Static Metadata Data Block */
#define HDMI_EDID_HDR_SMDB_MIN_LEN 3
/* EOTF(Electro-Optical Transfer Functions) */
struct HdmiEdidHdrSmdbEotf {
bool sdr; /* Traditional gamma - SDR Luminance Range */
bool hdr; /* Traditional gamma - HDR Luminance Range */
bool smpteSt2048; /* SMPTE ST 2084 */
bool hlg; /* Hybrid Log-Gamma (HLG) based on Recommendation ITU-R BT.2100-0 */
};
struct HdmiEdidHdrCap {
struct HdmiEdidHdrSmdbEotf eotf;
bool smType1; /* Static Metadata Type 1 */
uint8_t maxLuminancedata; /* Desired Content Max Luminance data */
uint8_t maxFrameAverageLuminanceData; /* Desired Content Max Frame-average Luminance data */
uint8_t minLuminanceData; /* Desired Content Min Luminance data */
};
/* edid extension block: YCBCR 4:2:0 Capability Map Data Block */
struct HdmiEdidYcbcr420Cap {
uint32_t onlySupportY420VicNum;
uint32_t onlySupportY420Format[HDMI_EDID_EXTENSION_MAX_VIC_COUNT];
uint32_t SupportY420VicNum;
uint32_t SupportY420Format[HDMI_EDID_EXTENSION_MAX_VIC_COUNT];
};
/* sink device cap */
struct HdmiSinkDeviceCapability {
uint8_t extBlockNum;
struct HdmiEdidVendorInfo vendorInfo;
struct HdmiEdidVersionInfo verInfo;
char sinkDeviceName[HDMI_EDID_MAX_SINK_NAME_COUNT];
struct HdmiEdidBasicDispParamInfo disp;
struct HdmiEdidEstablishedTimingsInfo establishedTimingsInfo;
struct HdmiEdidStdTimingInfo stdTimingsInfo[HDMI_EDID_STANDARD_TIMING_COUNT];
struct HdmiEdidColorInfo colorInfo;
struct HdmiEdidColorSpace colorSpace;
uint32_t preTimingCnt;
struct HdmiEdidPreferredTimingInfo preTimingInfo[HDMI_EDID_MAX_DETAILED_TIMING_COUNT];
uint32_t audioInfoCnt;
struct HdmiEdidAudioInfo audioInfo[HDMI_EDID_EXTENSION_AUDIO_CAP_COUNT];
struct HdmiEdidVideoInfo videoInfo;
uint32_t maxTmdsClk;
bool supportHdmi14;
bool supportHdmi20;
bool supportAudio;
struct HdmiEdidExtVsdbInfo vsdbInfo;
struct HdmiEdidExtHfVsdbInfo hfVsdbInfo;
bool supportAudioSpeaker[HDMI_EDID_AUDIO_SPEAKER_BUTT];
struct HdmiEdidColorimetry colorimetry;
struct HdmiEdidVideoCapability videoCap;
struct HdmiEdidYcbcr420Cap y420Cap;
struct HdmiEdidHdrCap hdrCap;
struct HdmiEdidVsvdbDolbyCap dolbyCap;
};
/*
* EDID(Extended Display Identification Data).
* The Source read the Sink's EDID in order to discover the Sink's configuration and/or capabilities.
*/
struct HdmiEdid {
bool edidPhase;
uint32_t rawLen;
uint8_t raw[HDMI_EDID_TOTAL_SIZE];
struct HdmiSinkDeviceCapability sinkCap;
};
typedef int32_t (*HdmiEdidPhaseFunc)(struct HdmiEdid *edid);
int32_t HdmiEdidReset(struct HdmiEdid *edid);
int32_t HdmiEdidPhase(struct HdmiEdid *edid);
int32_t HdmiEdidGetRaw(struct HdmiEdid *edid, uint8_t *raw, uint32_t len);
int32_t HdmiEdidRawDataRead(struct HdmiEdid *edid, struct HdmiDdc *ddc);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* HDMI_EDID_H */
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef HDMI_EVENT_H
#define HDMI_EVENT_H
#include "hdf_base.h"
#include "platform_core.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
/* HPD(hot plug detect) */
#define HDMI_READ_HPD_STATUS_DELAY 110 /* ms */
enum HdmiEventType {
HDMI_EVENT_HOTPLUG = 0,
HDMI_EVENT_HOTUNPLUG = 1,
HDMI_EVENT_DETECT_SINK = 2,
HDMI_EVENT_CEC_MSG = 3,
HDMI_EVENT_HDCP_MSG = 4,
HDMI_EVENT_ZERO_DRMIF_TIMEOUT = 5,
HDMI_EVENT_SWITCH_TO_HDRMODE_TIMEOUT = 6,
HDMI_EVENT_BUTT,
};
struct HdmiEventMsg {
struct PlatformMsg msg;
void *priv;
};
struct HdmiEvent {
bool plugged;
bool hpdDetected;
};
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* HDMI_EVENT_H */
+212
View File
@@ -0,0 +1,212 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef HDMI_FRL_H
#define HDMI_FRL_H
#include "hdf_base.h"
#include "osal_time.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
/* FRL(Fix Rate Link) */
enum HdmiFrlMode {
HDMI_FRL_MODE_TMDS = 0,
HDMI_FRL_MODE_FRL = 1,
HDMI_FRL_MODE_BUTT,
};
#define HDMI_FRL_3_LANES 3
#define HDMI_FRL_4_LANES 4
enum HdmiFrlWorkMode {
HDMI_FRL_WORK_MODE_NONE = 0,
HDMI_FRL_WORK_MODE_3L3G = 1, /* 3 lanes, 3Gbps per lane */
HDMI_FRL_WORK_MODE_3L6G = 2, /* 3 lanes, 6Gbps per lane */
HDMI_FRL_WORK_MODE_4L6G = 3, /* 4 lanes, 6Gbps per lane */
HDMI_FRL_WORK_MODE_4L8G = 4, /* 4 lanes, 8Gbps per lane */
HDMI_FRL_WORK_MODE_4L10G = 5, /* 4 lanes, 10Gbps per lane */
HDMI_FRL_WORK_MODE_4L12G = 6, /* 4 lanes, 12Gbps per lane */
HDMI_FRL_WORK_MODE_BUTT,
};
enum HdmiFrlBitRate {
HDMI_FRL_BIT_RATE_3 = 3,
HDMI_FRL_BIT_RATE_6 = 6,
HDMI_FRL_BIT_RATE_8 = 8,
HDMI_FRL_BIT_RATE_10 = 10,
HDMI_FRL_BIT_RATE_12 = 12,
HDMI_FRL_BIT_RATE_BUTT,
};
enum HdmiFrlTrainPattern {
HDMI_FRL_TRAIN_PATTERN_NULL = 0,
HDMI_FRL_TRAIN_PATTERN_LP1 = 1,
HDMI_FRL_TRAIN_PATTERN_LP2 = 2,
HDMI_FRL_TRAIN_PATTERN_LP3 = 3,
HDMI_FRL_TRAIN_PATTERN_LP4 = 4,
HDMI_FRL_TRAIN_PATTERN_LP5 = 5,
HDMI_FRL_TRAIN_PATTERN_LP6 = 6,
HDMI_FRL_TRAIN_PATTERN_LP7 = 7,
HDMI_FRL_TRAIN_PATTERN_LP8 = 8,
HDMI_FRL_TRAIN_PATTERN_REV = 9,
HDMI_FRL_TRAIN_PATTERN_0E = 14,
HDMI_FRL_TRAIN_PATTERN_0F = 15,
HDMI_FRL_TRAIN_PATTERN_BUTT,
};
enum HdmiFrlTrainStatus {
HDMI_FRL_TRAIN_STATUS_NULL = 0,
HDMI_FRL_TRAIN_STATUS_FAIL = 1,
HDMI_FRL_TRAIN_STATUS_SUCC = 2,
HDMI_FRL_TRAIN_STATUS_BUSY = 3,
HDMI_FRL_TRAIN_STATUS_BUTT,
};
enum HdmiFrlTrainingFailReason {
HDMI_FRL_TRAIN_FAIL_NORMAL,
HDMI_FRL_TRAIN_FAIL_FLT_TIMEOUT,
HDMI_FRL_TRAIN_FAIL_FLT_STEP_TIMEOUT,
HDMI_FRL_TRAIN_FAIL_RATE_CHANGE,
HDMI_FRL_TRAIN_FAIL_FFE_CHANGE,
HDMI_FRL_TRAIN_FAIL_BUTT
};
enum HdmiFrlTrainStep {
HDMI_FRL_TRAIN_STEP_READR_CHECK = 0,
HDMI_FRL_TRAIN_STEP_TRAIN_START = 1,
HDMI_FRL_TRAIN_STEP_RESULT_CHECK = 2,
HDMI_FRL_TRAIN_STEP_RATE_CHANGE = 3,
HDMI_FRL_TRAIN_STEP_RESULT_HANDLE = 4,
HDMI_FRL_TRAIN_STEP_RETRAIN_CHECK = 5,
HDMI_FRL_TRAIN_STEP_TRAIN_STOP = 6,
HDMI_FRL_TRAIN_STEP_BUTT,
};
enum HdmiFrlRateSelect {
HDMI_FRL_RATE_LITTLE = 0,
HDMI_FRL_RATE_BIG = 1,
HDMI_FRL_RATE_BUTT,
};
enum HdmiFrlPixelFormatMode {
HDMI_FRL_PIXEL_FORMAT_MODE_0 = 0,
HDMI_FRL_PIXEL_FORMAT_MODE_1 = 1,
HDMI_FRL_PIXEL_FORMAT_MODE_2 = 2,
HDMI_FRL_PIXEL_FORMAT_MODE_3 = 3,
};
enum HdmiFrlBypass {
HDMI_FRL_BYPASS_READ_CHECK = 0x01,
HDMI_FRL_BYPASS_RESULT_CHECK = 0x02,
HDMI_FRL_BYPASS_RETRAIN_CHECK = 0x04,
};
/*
* Feed Forward Equalizer(FFE)
* Tx terminal will use 0=TxFFE0 FFE in Link Training. If higher rate signal needs to be transmitted,
* Tx will decide higher FFE compensation through Link Training to ensure
* that video and audio data can be completely transmitted to the Sink terminal.
*/
enum HdmiFrlTxffeMode {
HDMI_FRL_TXFFE_MODE_0 = 0,
HDMI_FRL_TXFFE_MODE_1 = 1,
HDMI_FRL_TXFFE_MODE_2 = 2,
HDMI_FRL_TXFFE_MODE_3 = 3,
HDMI_FRL_TXFFE_MODE_BUTT,
};
enum HdmiFrlStrategyMode {
HDMI_FRL_STRATEGY_MODE_1,
HDMI_FRL_STRATEGY_MODE_2,
HDMI_FRL_STRATEGY_MODE_3,
HDMI_FRL_STRATEGY_MODE_BUTT
};
enum HdmiFrlStateMachineRunningState {
HDMI_FRL_STATE_MACHINE_NULL = 0,
HDMI_FRL_STATE_MACHINE_START = 1,
HDMI_FRL_STATE_MACHINE_STOP = 2,
};
struct HdmiFrlStateMachineInfo {
bool start;
enum HdmiFrlTrainStep trainingState;
enum HdmiFrlStateMachineRunningState machineState;
uint64_t startTime; /* ms */
uint32_t waitReadyTime; /* ms */
uint32_t waitHandleTime; /* ms */
uint32_t waitRetrainTime; /* ms */
uint32_t trainTimeout; /* ms */
uint32_t timeoutCnt;
};
struct HdmiFrlInfo {
uint8_t curFrlRate;
uint8_t minFrlRate;
uint8_t maxFrlRate;
uint8_t preFrlRate;
uint32_t trainFailCnt;
uint32_t trainMaxFailTimes;
uint32_t tmdsClock;
enum HdmiFrlMode perMode;
enum HdmiFrlMode mode;
enum HdmiFrlStrategyMode strategy;
enum HdmiFrlRateSelect rateSelect;
bool scdc;
bool ctsMode;
bool start;
bool work;
struct HdmiFrlStateMachineInfo machineInfo;
uint32_t trainingFailCnt;
uint32_t trainingMaxFailTimes;
};
struct HdmiFrl {
struct HdmiFrlInfo info;
void *priv;
};
struct HdmiFrlAudioNctsConfig {
enum HdmiSampleRate sampleRate;
enum HdmiFrlMode mode;
uint8_t frlRate;
uint32_t pixelClk;
uint32_t n;
uint32_t cts;
};
struct HdmiFrlTrainConfig {
bool frlNoTimeout;
uint8_t frlRate;
uint8_t txffe;
uint32_t trainTimeout;
};
struct HdmiFrlTrainRslt {
enum HdmiFrlTrainStatus status;
enum HdmiFrlTrainPattern pattern[HDMI_FRL_4_LANES];
enum HdmiFrlTrainingFailReason failReason;
};
void HdmiFrlEnable(struct HdmiFrl *frl, bool enable);
bool HdmiFrlSupport(struct HdmiFrl *frl);
int32_t HdmiFrlModeSelect(struct HdmiFrl *frl);
bool HdmiFrlModeChanged(struct HdmiFrl *frl);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* HDMI_FRL_H */
+214
View File
@@ -0,0 +1,214 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef HDMI_HDCP_H
#define HDMI_HDCP_H
#include "hdf_base.h"
#include "osal_mutex.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
/* HDCP(High-bandwidth Digital Content Protection) Sysytem. */
enum HdmiHdcpPortOffset {
/* HDCP 1.4 Spec */
HDMI_HDCP_BKSV = 0x00, /* Rd, 5 bytes */
HDMI_HDCP_RI = 0x08, /* Rd, 2 bytes */
HDMI_HDCP_PJ = 0x0A, /* Rd, 1 byte */
HDMI_HDCP_AKSV = 0x10, /* Wr, 5 bytes */
HDMI_HDCP_AINFO = 0x15, /* Wr, 1 byte */
HDMI_HDCP_AN = 0x18, /* Wr, 8 bytes */
HDMI_HDCP_V_H0 = 0x20, /* Rd, 4 bytes */
HDMI_HDCP_V_H1 = 0x24, /* Rd, 4 bytes */
HDMI_HDCP_V_H2 = 0x28, /* Rd, 4 bytes */
HDMI_HDCP_V_H3 = 0x2C, /* Rd, 4 bytes */
HDMI_HDCP_V_H4 = 0x30, /* Rd, 4 bytes */
HDMI_HDCP_BCAPS = 0x40, /* Rd, 1 byte */
HDMI_HDCP_BSTATUS = 0x41, /* Rd, 2 bytes */
HDMI_HDCP_KSV_FIFO = 0x43, /* Rd, 1 byte */
/* HDCP 2.2 Spec */
HDMI_HDCP_HDCP2VERSION = 0x50, /* Rd, 1 byte */
HDMI_HDCP_WRITE_MSG = 0x60, /* Wr, 1 byte */
HDMI_HDCP_RXSTATUS = 0x70, /* Rd, 2 bytes */
HDMI_HDCP_READ_MSG = 0x80, /* Rd, 1 byte */
};
/* HDCP 2.2 Read/Write Message Id */
enum HdmiHdcpMsgId {
HDMI_HDCP_MSG_AKE_INIT = 2, /* Write, 12 bytes */
HDMI_HDCP_MSG_AKE_SEND_CERT = 3, /* Read, 534 bytes */
HDMI_HDCP_MSG_AKE_NO_STORED_KM = 4, /* Write, 129 bytes */
HDMI_HDCP_MSG_AKE_STORED_KM = 5, /* Write, 33 bytes */
HDMI_HDCP_MSG_AKE_SEND_H_PRIME = 7, /* Read, 33 bytes */
HDMI_HDCP_MSG_AKE_SEND_PAIRING_INFO = 8, /* Read, 17 bytes */
HDMI_HDCP_MSG_LC_INIT = 9, /* Write, 9 bytes */
HDMI_HDCP_MSG_LC_SEND_L_PRIME = 10, /* Read, 33 bytes */
HDMI_HDCP_MSG_SKE_SEND_EKS = 11, /* Write, 25 bytes */
HDMI_HDCP_MSG_REPEATER_AUTH_SEND_RCVID_LIST = 12, /* Read, 22 + 5 * device_count bytes */
HDMI_HDCP_MSG_REPEATER_AUTH_SEND_ACK = 15, /* Write, 17 bytes */
HDMI_HDCP_MSG_REPEATER_AUTH_STREAM_MANAGE = 16, /* Write, 6 + 2 * k bytes */
HDMI_HDCP_MSG_REPEATER_AUTH_STREAM_READY = 17, /* Read, 33 bytes */
};
enum HdmiHdcpRegOptType {
/* HDCP 1.4 Spec */
HDMI_HDCP_OPT_WRITE_BKSV = 0x00,
HDMI_HDCP_OPT_WRITE_RI = 0x01,
HDMI_HDCP_OPT_WRITE_PJ = 0x02,
HDMI_HDCP_OPT_WRITE_V_H0 = 0x03,
HDMI_HDCP_OPT_WRITE_V_H1 = 0x04,
HDMI_HDCP_OPT_WRITE_V_H2 = 0x05,
HDMI_HDCP_OPT_WRITE_V_H3 = 0x06,
HDMI_HDCP_OPT_WRITE_V_H4 = 0x07,
HDMI_HDCP_OPT_WRITE_V_H_ALL = 0x08,
HDMI_HDCP_OPT_WRITE_BCAPS = 0x0C,
HDMI_HDCP_OPT_WRITE_BSTATUS = 0x0D,
HDMI_HDCP_OPT_WRITE_KSV_FIFO = 0x0E,
HDMI_HDCP_OPT_RESET_SHA = 0x0F,
HDMI_HDCP_OPT_CHECK_V = 0x10,
HDMI_HDCP_OPT_CHECK_R = 0x11,
HDMI_HDCP_OPT_AUTH_FAIL = 0x12,
HDMI_HDCP_OPT_AUTH_DONE = 0x13,
HDMI_HDCP_OPT_AUTH_CLOSE = 0x14,
};
#define HDMI_HDCP_MSG_BKSV_LEN 5
#define HDMI_HDCP_MSG_RI_LEN 2
#define HDMI_HDCP_MSG_PJ_LEN 1
#define HDMI_HDCP_MSG_AKSV_LEN 5
#define HDMI_HDCP_MSG_AINFO_LEN 1
#define HDMI_HDCP_MSG_AN_LEN 8
#define HDMI_HDCP_MSG_PER_VH_LEN 4
#define HDMI_HDCP_MSG_ALL_VH_LEN 20
#define HDMI_HDCP_MSG_BCAPS_LEN 1
#define HDMI_HDCP_MSG_BSTATUS_LEN 2
#define HDMI_HDCP_MSG_KSV_FIFO_LEN 1
#define HDMI_HDCP_DEVICE_COUNT_MAX 127
#define HDMI_HDCP_MSG_KSV_MAX_LEN (5 * HDMI_HDCP_DEVICE_COUNT_MAX)
#define HDMI_HDCP_GET_KSV_LEN(x) (5 * x)
#define HDMI_HDCP_AKSV_ONE_NUM 20
#define HDMI_HDCP_BCAPS_REPEATER_MARK 0x40
#define HDMI_HDCP_BCAPS_KSV_FIFO_READY_MARK 0x20
#define HDMI_HDCP_DEFAULT_READ_REG_TRY 100
#define HDMI_HDCP_WAIT_KSV_LIST_TIMES 5000 /* 5s */
#define HDMI_HDCP_WAIT_KSV_LIST_READ_REG_INTERVAL 20 /* 20ms */
#define HDMI_HDCP_WAIT_KSV_LIST_READ_REG_CNT \
(HDMI_HDCP_WAIT_KSV_LIST_TIMES / HDMI_HDCP_WAIT_KSV_LIST_READ_REG_INTERVAL)
#define HDMI_HDCP_BSTATUS_DEVICE_COUNT_MARK 0x7F
#define HDMI_HDCP_BSTATUS_MAX_DEVS_EXCEEDED_MARK (1 << 7)
#define HDMI_HDCP_BSTATUS_MAX_CASCADE_EXCEEDED_MARK (1 << 11)
#define HDMI_HDCP_BSTATUS_DEPTH_MARK 0x07
#define HDMI_HDCP_BSTATUS_DEPTH_SHIFT 8
#define HDMI_HDCP_MSG_HDCP2VERSION_LEN 1
#define HDMI_HDCP_MSG_RXSTATUS_LEN 2
#define HDMI_HDCP_MSG_AKE_INIT_LEN 12
#define HDMI_HDCP_MSG_AKE_CERT_LEN 534
#define HDMI_HDCP_MSG_AKE_NO_STORED_KM_LEN 129
#define HDMI_HDCP_MSG_AKE_STORED_KM_LEN 33
#define HDMI_HDCP_MSG_AKE_H_PRIME_LEN 33
#define HDMI_HDCP_MSG_AKE_PAIRING_INFO 17
#define HDMI_HDCP_MSG_LC_INIT_LEN 9
#define HDMI_HDCP_MSG_LC_L_PRIME_LEN 33
#define HDMI_HDCP_MSG_SKE_EKS_LEN 25
#define HDMI_HDCP_MSG_AUTH_RCVID_LIST_LEN (22 + 5 * 31)
#define HDMI_HDCP_MSG_REPEATER_AUTH_ACK_LEN 17
#define HDMI_HDCP_MSG_REPEATER_AUTH_STREAM_MANAGE_LEN (6 + 2 * 31)
#define HDMI_HDCP_MSG_REPEATER_AUTH_STREAM_READY_LEN 33
#define HDMI_HDCP_2_2_VERSION 2
#define HDMI_HDCP_GET_AUTH_RCVID_LIST_LEN(x) (22 + 5 * x)
struct HdmiHdcpMsg {
/* HDCP 1.4 message */
uint8_t bksv[HDMI_HDCP_MSG_BKSV_LEN];
uint8_t ri[HDMI_HDCP_MSG_RI_LEN];
uint8_t pj;
uint8_t aksv[HDMI_HDCP_MSG_AKSV_LEN];
uint8_t ainfo;
uint8_t an[HDMI_HDCP_MSG_AN_LEN];
uint8_t vh[HDMI_HDCP_MSG_ALL_VH_LEN];
uint8_t bcaps;
uint8_t bstatus[HDMI_HDCP_MSG_BSTATUS_LEN];
uint8_t ksvList[HDMI_HDCP_MSG_KSV_MAX_LEN];
uint32_t ksvLen;
/* HDCP 2.2 Message */
uint8_t Hdcp2Version;
uint8_t rxStatus[HDMI_HDCP_MSG_RXSTATUS_LEN];
uint8_t akeInit[HDMI_HDCP_MSG_AKE_INIT_LEN];
uint8_t akeCert[HDMI_HDCP_MSG_AKE_CERT_LEN];
uint8_t akeNoStoredKm[HDMI_HDCP_MSG_AKE_NO_STORED_KM_LEN];
uint8_t akeStoredKm[HDMI_HDCP_MSG_AKE_STORED_KM_LEN];
uint8_t akeHPrime[HDMI_HDCP_MSG_AKE_H_PRIME_LEN];
uint8_t akePairingInfo[HDMI_HDCP_MSG_AKE_PAIRING_INFO];
uint8_t lcInit[HDMI_HDCP_MSG_LC_INIT_LEN];
uint8_t lcLPrime[HDMI_HDCP_MSG_LC_L_PRIME_LEN];
uint8_t skeEks[HDMI_HDCP_MSG_SKE_EKS_LEN];
uint8_t rxIdList[HDMI_HDCP_MSG_AUTH_RCVID_LIST_LEN];
uint32_t rxIdListLen;
uint8_t authAck[HDMI_HDCP_MSG_REPEATER_AUTH_ACK_LEN];
uint8_t authStreamManage[HDMI_HDCP_MSG_REPEATER_AUTH_STREAM_MANAGE_LEN];
uint32_t authStreamManageLen;
uint8_t authStreamReady[HDMI_HDCP_MSG_REPEATER_AUTH_STREAM_READY_LEN];
};
enum HdmiHdcpAuthState {
HDMI_HDCP_AUTH_INACTIVE = 0,
HDMI_HDCP_AUTH_AKSV_INVALID = 1,
HDMI_HDCP_AUTH_DOING = 2,
HDMI_HDCP_AUTH_DONE = 3,
HDMI_HDCP_AUTH_FAIL = 4,
};
#define HDMI_HDCP_AUTH_MAX_RETRY_CNT 10
struct HdmiHdcp {
struct OsalMutex hdcpMutex;
enum HdmiHdcpAuthState state;
uint8_t authRetryCnt;
/* HDCP 1.4 */
uint8_t aksv[HDMI_HDCP_MSG_AKSV_LEN]; /* need driver to generate */
uint8_t an[HDMI_HDCP_MSG_AN_LEN]; /* need driver to generate */
uint8_t bksv[HDMI_HDCP_MSG_BKSV_LEN];
uint8_t bcaps;
uint8_t ri[HDMI_HDCP_MSG_RI_LEN];
uint8_t bstatus[HDMI_HDCP_MSG_BSTATUS_LEN];
uint8_t deviceCount;
uint8_t ksvList[HDMI_HDCP_MSG_KSV_MAX_LEN];
uint32_t ksvLen;
uint8_t vh[HDMI_HDCP_MSG_ALL_VH_LEN];
bool aksvValid;
void *priv;
};
struct HdmiHdcpStatus {
bool hdcp22;
bool hdcp14;
uint8_t bksv[HDMI_HDCP_MSG_BKSV_LEN];
uint8_t aksv[HDMI_HDCP_MSG_AKSV_LEN];
};
int32_t HdmiHdcpOpen(struct HdmiHdcp *hdcp);
void HdmiHdcpClose(struct HdmiHdcp *hdcp);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* HDMI_HDCP_H */
+65
View File
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef HDMI_HPR_H
#define HDMI_HPR_H
#include "hdf_base.h"
#include "hdmi_if.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
/* HDR(High Dynamic Range) Sysytem. */
#define HDMI_ZERO_DRMIF_SEND_TIME 2000
#define HDMI_HDR_STATE_CHANGE_TIME 500
enum HdmiHdrTimerType {
HDMI_HDR_TIMER_ZERO_DRMIF,
HDMI_HDR_TIMER_SDR_TO_HDR10,
HDMI_HDR_TIMER_TYPE_BUTT
};
enum HdmiHdrState {
HDMI_HDR_STATE_NONE, /* HDR state change, SDR->HDR10 don't change anything */
HDMI_HDR_STATE_OE, /* HDR state change, SDR->HDR10 output disable and enable */
HDMI_HDR_STATE_AVMUTE, /* HDR state change, SDR->HDR10 send avmute */
HDMI_HDR_STATE_BUTT
};
struct HdmiHdrTimerConfig {
enum HdmiHdrTimerType timerType;
bool start;
uint32_t time;
};
struct HdmiHdrInfo {
enum HdmiHdrState state; /* Make sure that switch smoothly from non-HDR10 to HDR10. */
struct HdmiHdrTimerConfig zeroDrmIfTimer; /* Send zero DRM infoframe when the HDR mode from HDR10 to non-HDR10. */
struct HdmiHdrTimerConfig stateChangeTimer; /* */
};
struct HdmiHdr {
struct HdmiHdrInfo info;
void *priv;
};
int32_t HdmiHdrAttrHandle(struct HdmiHdr *hdr, struct HdmiHdrAttr *curAttr);
int32_t HdmiHdrDrmInfoframeStop(struct HdmiHdr *hdr);
int32_t HdmiHdrModeChangeTimeout(struct HdmiHdr *hdr);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* HDMI_HPR_H */
@@ -0,0 +1,466 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef HDMI_INFOFRAME_H
#define HDMI_INFOFRAME_H
#include "hdmi_common.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
/*
* An InfoFrame packet carries one InfoFrame. The InfoFrame provided by HDMI is limited to 30
* bytes plus a checksum byte. HDMI Sources are required, in some cases, to use the AVI InfoFrame and Audio InfoFrame
* and recommended in other cases. Other InfoFrames specified in CEA-861 Spec are optional.
*
* TMDS is used to carry all audio and video data as well as auxiliary data, including AVI(Auxiliary Video information)
* and Audio InfoFrames that describe the active audio and video streams.
*
*/
#define HDMI_INFOFRAME_LEN 32
#define HDMI_INFOFRAME_PACKET_HEADER_LEN 4
#define HDMI_AVI_INFOFRAME_LEN 13
#define HDMI_AUDIO_INFOFRAME_LEN 10
#define HDMI_DRM_INFOFRAME_LEN 26
#define HDMI_SPD_INFOFRAME_LEN 25
#define HDMI_INFOFRAME_CHECKSUM 256
enum HdmiPacketType {
HDMI_PACKET_TYPE_NULL = 0x00, /* Null Packet */
HDMI_PACKET_TYPE_AUDIO_CLOCK_REGENERATION = 0x01, /* Audio Clock Regeneration(N/CTS) */
HDMI_PACKET_TYPE_AUDIO_SAMPLE = 0x02, /* Audio Samlpe(L-PCM and IEC 61937 compressed formats) */
HDMI_PACKET_TYPE_GENERAL_CONTROL = 0x03, /* General Control Packet */
HDMI_PACKET_TYPE_ACP = 0x04, /* ACP(Audio Content Protection Packet) */
HDMI_PACKET_TYPE_ISRC1 = 0x05, /* ISRC(International Standard Recording Code) */
HDMI_PACKET_TYPE_ISRC2 = 0x06,
HDMI_PACKET_TYPE_ONE_BIT_AUDIO_SAMPLE = 0x07, /* One Bit Audio Sample Packet */
HDMI_PACKET_TYPE_DST_AUDIO = 0x08, /* DST(Diret Stream Transport) Audio Packet */
HDMI_PACKET_TYPE_HBR_AUDIO_STREAM = 0x09, /* HBR(High Bitrate) Audio Stream Packet */
HDMI_PACKET_TYPE_GAMUT_METADATA = 0x0a, /* gamut metadata packet */
/* infoframe type */
HDMI_INFOFRAME_PACKET_TYPE_VS = 0x81, /* Verdor-Specific */
HDMI_INFOFRAME_PACKET_TYPE_AVI = 0x82, /* Auxiliary Video Information */
HDMI_INFOFRAME_PACKET_TYPE_SPD = 0x83, /* Source Product Description */
HDMI_INFOFRAME_PACKET_TYPE_AUDIO = 0x84, /* Audio */
HDMI_INFOFRAME_PACKET_TYPE_MPEG = 0x85, /* MPEG Source */
HDMI_INFOFRAME_PACKET_TYPE_GBD = 0x86, /* gamut boundary description */
HDMI_INFOFRAME_PACKET_TYPE_DRM = 0x87, /* Dynamic Range and Mastering */
HDMI_PACKET_TYPE_BUTT,
};
struct HdmiInfoframeHeader {
enum HdmiPacketType type;
uint8_t verNum;
uint8_t len;
};
/* Verdor-Specific infoframe details. */
#define HDMI_VENDOR_1_4_MAX_3D_METADAT_LEN 20
#define HDMI_VENDOR_USER_DATA_MAX_LEN 22
#define HDMI_VENDOR_1_4_FORMAT_MARK 0x07
#define HDMI_VENDOR_1_4_FORMAT_SHIFT 5
#define HDMI_VENDOR_3D_STRUCTURE_MARK 0x0f
#define HDMI_VENDOR_3D_STRUCTURE_SHIFT 4
#define HDMI_VENDOR_3D_EXT_DATA_MARK 0x0f
#define HDMI_VENDOR_3D_EXT_DATA_SHIFT 4
#define HDMI_VSIF_VERSION 1
enum HdmiIeeeOui {
HDMI_IEEE_OUI_1_4 = 0x000c03,
HDMI_IEEE_OUI_2_0 = 0x045dd8,
};
enum HdmiVsVideoFormat {
HDMI_VS_VIDEO_FORMAT_NULL = 0,
HDMI_VS_VIDEO_FORMAT_4K = 1,
HDMI_VS_VIDEO_FORMAT_3D = 2,
HDMI_VS_VIDEO_FORMAT_BUTT,
};
enum HdmiVs3dExtData {
HDMI_3D_PICTURE_HORIZONTAL_ODD_LEFT_ODD_RIGHT = 0,
HDMI_3D_PICTURE_HORIZONTAL_ODD_LEFT_EVEN_RIGHT = 1,
HDMI_3D_PICTURE_HORIZONTAL_EVEN_LEFT_ODD_RIGHT = 2,
HDMI_3D_PICTURE_HORIZONTAL_EVEN_LEFT_EVEN_RIGHT = 3,
HDMI_3D_PICTURE_MATRIX_ODD_LEFT_ODD_RIGHT = 4,
HDMI_3D_PICTURE_MATRIX_ODD_LEFT_EVEN_RIGHT = 5,
HDMI_3D_PICTURE_MATRIX_EVEN_LEFT_ODD_RIGHT = 6,
HDMI_3D_PICTURE_MATRIX_EVEN_LEFT_EVEN_RIGHT = 7,
HDMI_3D_PICTURE_BUTT,
};
struct HdmiVs14VsifContent {
enum HdmiIeeeOui oui;
enum HdmiVsVideoFormat format;
enum Hdmi4kVic vic;
bool _3dMetaPresent;
enum HdmiVideo3dStructure _3dStruct;
enum HdmiVs3dExtData _3dExtData;
uint8_t _3dMetadataType;
uint8_t _3dMetadataLen;
uint8_t _3dMetadata[HDMI_VENDOR_1_4_MAX_3D_METADAT_LEN];
};
struct HdmiVsUserVsifContent {
enum HdmiIeeeOui oui;
enum HdmiVsVideoFormat format;
enum Hdmi4kVic vic;
bool _3dMetaPresent;
enum HdmiVideo3dStructure _3dStruct;
uint8_t len;
uint8_t data[HDMI_VENDOR_USER_DATA_MAX_LEN];
};
struct HdmiForumVsifContent {
enum HdmiIeeeOui oui;
uint8_t version;
bool _3dValid;
uint8_t _3dFStructure;
bool _3dAdditionalInfoPresent;
bool _3dDisparityDataPresent;
bool _3dMetaPresent;
uint8_t _3dFExtData;
uint8_t _3dDualView;
uint8_t _3dViewDependency;
uint8_t _3dPreferred2dView;
uint8_t _3dDisparityDataVersion;
uint8_t _3dDisparityDataLen;
uint8_t _3dDisparityData[10];
uint8_t _3dMetadataType;
uint8_t _3dMetadataLen;
uint8_t _3dMetadata[10];
};
struct HdmiVsInfoframe {
enum HdmiPacketType type;
uint8_t verNum;
uint8_t len;
union {
struct HdmiVs14VsifContent _14Vsif;
struct HdmiVsUserVsifContent userVsif;
struct HdmiForumVsifContent forumVsif;
} vsifContent;
};
/* AVI infoframe details. */
#define HDMI_AVI_COLOR_SPACE_MARK 0x03
#define HDMI_AVI_SCAN_MODE_MARK 0x03
#define HDMI_AVI_COLOR_SPACE_SHIFT 5
#define HDMI_AVI_ACTIVE_INFORMATION_SHIFT 4
#define HDMI_AVI_HORIZONTAL_BAR_SHIFT 3
#define HDMI_AVI_VERTICAL_BAR_SHIFT 2
#define HDMI_AVI_COLORIMETRY_MARK 0x03
#define HDMI_AVI_PICTURE_ASPECT_RATE_MARK 0x03
#define HDMI_AVI_ACTIVE_FORMAT_ASPECT_RATE_MARK 0x0f
#define HDMI_AVI_COLORIMETRY_SHIFT 6
#define HDMI_AVI_PICTURE_ASPECT_RATE_SHIFT 4
#define HDMI_AVI_EXT_COLORIMETRY_MARK 0x07
#define HDMI_AVI_EXT_QUANTIZATION_RANGE_MARK 0x03
#define HDMI_AVI_NUPS_RANGE_MARK 0x03
#define HDMI_AVI_IT_CONTENT_SHIFT 7
#define HDMI_AVI_EXT_COLORIMETRY_SHIFT 4
#define HDMI_AVI_EXT_QUANTIZATION_RANGE_SHIFT 2
#define HDMI_AVI_YCC_QUANTIZATION_RANGE_MARK 0x03
#define HDMI_AVI_IT_CONTENT_TYPE_MARK 0x03
#define HDMI_AVI_PIXEL_REPETION_FACTOR_MARK 0x0f
#define HDMI_AVI_YCC_QUANTIZATION_RANGE_SHIFT 6
#define HDMI_AVI_IT_CONTENT_TYPE_SHIFT 4
#define HDMI_AVI_BAR_MODE_MARK 0xff
#define HDMI_AVI_BAR_MODE_SHIFT 8
#define HDMI_AVI_VERSION2 2
#define HDMI_AVI_VERSION3 3
#define HDMI_AVI_VERSION4 4
#define HDMI_AVI_Y2_MASK (0x1 << 2)
enum HdmiScanMode {
HDMI_SCAN_MODE_NO_DATA = 0,
HDMI_SCAN_MODE_OVERSCAN = 1,
HDMI_SCAN_MODE_UNDERSCAN = 2,
HDMI_SCAN_MODE_FUTURE = 3,
};
enum HdmiItContentType {
HDMI_IT_CONTENT_TYPE_GRAPHICS = 0,
HDMI_IT_CONTENT_TYPE_PHOTO = 1,
HDMI_IT_CONTENT_TYPE_CINEMA = 2,
HDMI_IT_CONTENT_TYPE_GAME = 3,
};
struct HdmiAviInfoframe {
enum HdmiPacketType type;
uint8_t verNum;
uint8_t len;
enum HdmiScanMode scanMode;
bool vertBarInfoPresent;
bool horizBarInfoPresent;
bool activeFormatInformationPresent;
enum HdmiColorSpace colorSpace;
enum HdmiActiveFormatAspectRatio activeAspect;
enum HdmiPictureAspectRatio pictureAspect;
enum HdmiColorimetry colorimetry;
enum HdmiNups nups;
enum HdmiQuantizationRange range;
enum HdmiExtendedColorimetry extColorimetry;
bool itc; /* IT content */
uint8_t vic;
uint8_t pixelRepetitionFactor;
enum HdmiItContentType itcType;
enum HdmiYccQuantizationRange yccRange;
uint16_t topBar;
uint16_t bottomBar;
uint16_t leftBar;
uint16_t rightBar;
};
/* Audio infoframe details. */
#define HDMI_AUDIO_INFOFRAME_VERSION 1
#define HDMI_AUDIO_CODING_TYPE_MARK 0x0f
#define HDMI_AUDIO_CHANNEL_COUNT_MARK 0x07
#define HDMI_AUDIO_CODING_TYPE_SHIFT 4
#define HDMI_AUDIO_SAMPLE_FREQUENCY_MARK 0x07
#define HDMI_AUDIO_SAMPLE_SIZE_MARK 0x03
#define HDMI_AUDIO_SAMPLE_FREQUENCY_SHIFT 2
#define HDMI_AUDIO_CXT_MARK 0x1f
#define HDMI_AUDIO_LEVEL_SHIFT_VALUE_MARK 0x0f
#define HDMI_AUDIO_LEF_PLAYBACK_LEVEL_MARK 0x03
#define HDMI_AUDIO_DM_INH_SHIFT 7
#define HDMI_AUDIO_LEVEL_SHIFT_VALUE_SHIFT 3
enum HdmiAudioSampleSize {
HDMI_AUDIO_SAMPLE_SIZE_STREAM = 0,
HDMI_AUDIO_SAMPLE_SIZE_16_BIT = 1,
HDMI_AUDIO_SAMPLE_SIZE_20_BIT = 2,
HDMI_AUDIO_SAMPLE_SIZE_24_BIT = 3,
};
enum HdmiAudioSampleFrequency {
HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM = 0,
HDMI_AUDIO_SAMPLE_FREQUENCY_32K = 1,
HDMI_AUDIO_SAMPLE_FREQUENCY_44_1K = 2,
HDMI_AUDIO_SAMPLE_FREQUENCY_48K = 3,
HDMI_AUDIO_SAMPLE_FREQUENCY_88_2K = 4,
HDMI_AUDIO_SAMPLE_FREQUENCY_96K = 5,
HDMI_AUDIO_SAMPLE_FREQUENCY_176_4K = 6,
HDMI_AUDIO_SAMPLE_FREQUENCY_192K = 7,
};
enum HdmiAudioCodingExtType {
/* Refer to Audio Coding Type (CT) field in Data Byte 1 */
HDMI_AUDIO_CODING_EXT_TYPET_CT = 0,
/*
* The next three CXT values are defined in CEA-861-E only.
* They do not exist in older versions, and in CEA-861-F they are
* defined as 'Not in use'.
*/
HDMI_AUDIO_CODING_EXT_TYPET_HE_AAC = 1,
HDMI_AUDIO_CODING_EXT_TYPET_HE_AAC_V2 = 2,
HDMI_AUDIO_CODING_EXT_TYPET_MPEG_SURROUND = 3,
HDMI_AUDIO_CODING_EXT_TYPET_MPEG4_HE_AAC = 4,
HDMI_AUDIO_CODING_EXT_TYPET_MPEG4_HE_AAC_V2 = 5,
HDMI_AUDIO_CODING_EXT_TYPET_MPEG4_AAC_LC = 6,
HDMI_AUDIO_CODING_EXT_TYPET_DRA = 7,
HDMI_AUDIO_CODING_EXT_TYPET_MPEG4_HE_AAC_SURROUND = 8,
HDMI_AUDIO_CODING_EXT_TYPET_RESERVED = 9,
HDMI_AUDIO_CODING_EXT_TYPET_MPEG4_AAC_LC_SURROUND = 10,
HDMI_AUDIO_CODING_EXT_TYPET_MPEGH_3D_AUDIO = 11,
HDMI_AUDIO_CODING_EXT_TYPET_AC4 = 12,
HDMI_AUDIO_CODING_EXT_TYPET_LPCM_3D_AUDIO = 13,
HDMI_AUDIO_CODING_EXT_TYPET_BUTT,
};
/* LEF(Low Frequency Effects) playback level. */
enum HdmiAudioLfePlaybackLevel {
HDMI_AUDIO_LFE_PLAYBACK_NULL = 0,
HDMI_AUDIO_LFE_PLAYBACK_0DB = 1,
HDMI_AUDIO_LFE_PLAYBACK_10DB = 2,
HDMI_AUDIO_LFE_PLAYBAC_BUTT,
};
struct HdmiAudioInfoframe {
enum HdmiPacketType type;
uint8_t verNum;
uint8_t len;
uint8_t channelCount;
enum HdmiAudioCodingType codingType;
enum HdmiAudioSampleSize sampleSize;
enum HdmiAudioSampleFrequency sampleFreq;
enum HdmiAudioCodingExtType codingExtType;
uint8_t channelAllocation;
enum HdmiAudioLfePlaybackLevel playBackLevel;
uint8_t levelShiftValue;
bool dmInh; /* Down-mix Inhibit Flag */
};
/* Source Product Description infoframe details. */
#define HDMI_SPD_VENDOR_NAME_LEN 8
#define HDMI_SPD_PRODUCT_DESCRIPTION_LEN 16
#define HDMI_SPD_VERSION 1
/* SDI(Source Device Information) */
enum HdmiSpdSdi {
HDMI_SPD_SDI_NULL = 0,
HDMI_SPD_SDI_DIGITAL_STB = 1,
HDMI_SPD_SDI_DVD_PLAYER = 2,
HDMI_SPD_SDI_D_VHS = 3,
HDMI_SPD_SDI_HDD_VIDEORECORDER = 4,
HDMI_SPD_SDI_DVC = 5,
HDMI_SPD_SDI_DSC = 6,
HDMI_SPD_SDI_VIDEO_CD = 7,
HDMI_SPD_SDI_GAME = 8,
HDMI_SPD_SDI_PC_GENERAL = 9,
HDMI_SPD_SDI_BLU_RAY_DIS = 10,
HDMI_SPD_SDI_SUPER_AUDIO_CD = 11,
HDMI_SPD_SDI_HDDVD = 12,
HDMI_SPD_SDI_PMP = 13,
HDMI_SPD_SDI_BUTT,
};
struct HdmiSpdInfoframe {
enum HdmiPacketType type;
uint8_t verNum;
uint8_t len;
char vendorName[HDMI_SPD_VENDOR_NAME_LEN];
char productDescription[HDMI_SPD_PRODUCT_DESCRIPTION_LEN];
enum HdmiSpdSdi sdi;
};
/* Dynamic Range and Mastering infoframe details. */
#define HDMI_DRM_METADATA_MARK 0xff
#define HDMI_DRM_METADATA_SHIFT 8
#define HDMI_DRM_INFOFRAME_VERSION 1
struct HdmiDrmInfoframe {
enum HdmiPacketType type;
uint8_t verNum;
uint8_t len;
enum HdmiEotfType eotfType;
enum HdmiStaticMetadataType metadataType;
union HdmiStaticMetadataDescriptor des;
};
/* GBD(gamut boundary description) */
union HdmiGbdHb1{
struct {
uint8_t affectedGamutSeqNum : 4; /* [0:3] */
uint8_t gbdProfil : 3; /* [4:5] */
uint8_t reseverd: 1; /* [6] */
uint8_t noCrntGbd : 1; /* [7] */
} bits;
uint8_t val;
};
union HdmiGbdHb2{
struct {
uint8_t currentGamutSeqNum : 4; /* [0:3] */
uint8_t packetSeq : 2; /* [4:5] */
uint8_t nextField : 1; /* [7] */
} bits;
uint8_t val;
};
union HdmiGbdRangeData0 {
struct {
uint8_t gbdColorSpace : 3; /* [0:2] */
uint8_t gbdColorPercision : 2; /* [3:4] */
uint8_t rsvd: 2; /* [5:6] */
uint8_t formatFlag : 1; /* [7] */
} bits;
uint8_t val;
};
struct HdmiGbdPacket {
uint8_t hb0;
union HdmiGbdHb1 hb1;
union HdmiGbdHb2 hb2;
union HdmiGbdRangeData0 data0;
uint8_t minRedDataH;
uint8_t midRedData; /* Min_Red_Data_L | Max_Red_Data_H */
uint8_t maxRedDataL;
uint8_t minGreenDataH;
uint8_t midGreenData; /* Min_Green_Data_L | Max_Green_Data_H */
uint8_t maxGreenDataL;
uint8_t minBlueDataH;
uint8_t midBlueData; /* Min_Blue_Data_L | Max_Blue_Data_H */
uint8_t maxBlueDataL;
};
union HdmiInfoframeInfo {
struct HdmiInfoframeHeader header;
struct HdmiVsInfoframe vs;
struct HdmiAviInfoframe avi;
struct HdmiAudioInfoframe audio;
struct HdmiSpdInfoframe spd;
struct HdmiDrmInfoframe drm;
struct HdmiGbdPacket gbd;
};
/*
* Infoframe: A data structure defined in CEA-861-D that is designed to carry a variety of auxiliary data items
* regarding the audio or video streams or the source device and is carried from Source to Sink across HDMI.
*/
struct HdmiInfoframe {
enum HdmiPacketType infoframeType;
bool hdrSupport;
struct HdmiVsInfoframe vs;
struct HdmiAviInfoframe avi;
struct HdmiAudioInfoframe audio;
struct HdmiSpdInfoframe spd;
struct HdmiDrmInfoframe drm;
struct HdmiGbdPacket gbd;
struct HdmiVsUserVsifContent userVsif;
void *priv;
};
struct HdmiInfoframeStatus {
bool vsifEnable;
bool aviEnable;
bool audioEnable;
bool spdEnable;
bool drmEnable;
bool gdbEnable;
uint8_t avi[HDMI_INFOFRAME_LEN];
uint8_t audio[HDMI_INFOFRAME_LEN];
uint8_t vsif[HDMI_INFOFRAME_LEN];
uint8_t spd[HDMI_INFOFRAME_LEN];
uint8_t drm[HDMI_INFOFRAME_LEN];
uint8_t gdb[HDMI_INFOFRAME_LEN];
};
int32_t HdmiAudioInfoframeSend(struct HdmiInfoframe *frame, bool enable);
int32_t HdmiAviInfoframeSend(struct HdmiInfoframe *frame, bool enable);
int32_t HdmiDrmInfoframeSend(struct HdmiInfoframe *frame, bool enable);
int32_t HdmiVsInfoframeSend(struct HdmiInfoframe *frame, bool enable, bool dolbyEnable);
int32_t HdmiSpdInfoframeSend(struct HdmiInfoframe *frame, bool enable,
char *vendorName, char *productName, enum HdmiSpdSdi sdi);
int32_t HdmiInfoframeGetInfo(struct HdmiInfoframe *frame, enum HdmiPacketType type,
union HdmiInfoframeInfo *infoframe);
int32_t HdmiInfoframeSetInfo(struct HdmiInfoframe *frame, enum HdmiPacketType type,
union HdmiInfoframeInfo *infoframe);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* HDMI_INFOFRAME_H */
+41
View File
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef HDMI_NCTS_H
#define HDMI_NCTS_H
#include "hdf_base.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
/* N/CTS(Cycle Time Stamp), see hdmi1.4 spec section 7.2. */
#define HDMI_NCTS_FACTOR 128
#define HDMI_NCTS_N_DEFAULT 6144
#define HDMI_NCTS_TMDS_DEVIATION 20
struct HdmiAudioNCts {
uint32_t sampleRate; /* audio sample rate(fs) */
uint32_t tmdsClock;
uint32_t n;
uint32_t cts;
};
uint32_t HdmiGetN(uint32_t sampleRate, uint32_t tmdsClock);
uint32_t HdmiGetCts(uint32_t sampleRate, uint32_t tmdsClock);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* HDMI_NCTS_H */
+321
View File
@@ -0,0 +1,321 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef HDMI_SCDC_H
#define HDMI_SCDC_H
#include "hdf_base.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
/* SCDC(Status and Control Data Channel) */
#define HDMI_SCDC_HDMI20_VERSION 1
#define HDMI_SCDC_DEFAULT_SCRAMBLE_TIMEOUT 200 /* ms */
/*
* SCDCS(Status and Control Data Channel Structure).
* see hdmi2.0 spec table 10-15.
*/
enum HdmiScdcsOffset {
HDMI_SCDCS_OFFSET_SINK_VERSION = 0x01,
HDMI_SCDCS_OFFSET_SOURCE_VERSION = 0x02,
HDMI_SCDCS_OFFSET_UPDATE_0 = 0x10,
HDMI_SCDCS_OFFSET_UPDATE_1 = 0x11,
HDMI_SCDCS_OFFSET_TMDS_CONFIG = 0x20,
HDMI_SCDCS_OFFSET_SCRAMBLER_STATUS = 0x21,
HDMI_SCDCS_OFFSET_CONFIG_0 = 0x30,
HDMI_SCDCS_OFFSET_CONFIG_1 = 0x31,
HDMI_SCDCS_OFFSET_TEST_CONFIG_1 = 0x35,
HDMI_SCDCS_OFFSET_STASTUS_FLAG_0 = 0x40,
HDMI_SCDCS_OFFSET_STASTUS_FLAG_1 = 0x41,
HDMI_SCDCS_OFFSET_STASTUS_FLAG_2 = 0x42,
HDMI_SCDCS_OFFSET_ERR_DET_0_L = 0x50,
HDMI_SCDCS_OFFSET_ERR_DET_0_H = 0x51,
HDMI_SCDCS_OFFSET_ERR_DET_1_L = 0x52,
HDMI_SCDCS_OFFSET_ERR_DET_1_H = 0x53,
HDMI_SCDCS_OFFSET_ERR_DET_2_L = 0x54,
HDMI_SCDCS_OFFSET_ERR_DET_2_H = 0x55,
HDMI_SCDCS_OFFSET_ERR_DET_CHECKSUM = 0x56,
HDMI_SCDCS_OFFSET_TEST_CONFIG_0 = 0xC0,
HDMI_SCDCS_OFFSET_IEEE_OUI_3TH = 0xD0,
HDMI_SCDCS_OFFSET_IEEE_OUI_2ND = 0xD1,
HDMI_SCDCS_OFFSET_IEEE_OUI_1ST = 0xD2,
HDMI_SCDCS_OFFSET_DEVICE_ID_START = 0xD3,
HDMI_SCDCS_OFFSET_DEVICE_ID_END = 0xDD,
HDMI_SCDCS_OFFSET_SPECIFIC_START = 0xDE,
HDMI_SCDCS_OFFSET_SPECIFIC_END = 0xFF,
};
/*
* see HDMI2.1 section 10.4.1.3.
* All update flags are readable and writable.
* The purpose of these flags is to provide a mechanism for the sink device to efficiently inform the source device
* that additional source device action may be required.
*/
union HdmiScdcsUpdateFlag0 {
uint8_t data;
struct {
uint8_t statusUpdate : 1; /* The sink shall set this bit when value is changed in the Status Flag register. */
uint8_t cedUpdate : 1; /* ced(character error detection) register. */
uint8_t rrTest : 1; /* rr(Read Request) */
uint8_t srcTestUpdate : 1;
uint8_t frlStart : 1;
uint8_t fltUpdate : 1;
uint8_t rsedUpdate : 1;
uint8_t reserved : 1;
} bits;
};
#define HDMI_SCDC_STATUS_UPDATE_MARK (1 << 0)
#define HDMI_SCDC_CED_UPDATE_MARK (1 << 1)
#define HDMI_SCDC_RR_TEST_MARK (1 << 2)
#define HDMI_SCDC_SRC_TEST_UPDATE_MARK (1 << 3)
#define HDMI_SCDC_FRL_START_MARK (1 << 4)
#define HDMI_SCDC_FLT_UPDATE_MARK (1 << 5)
#define HDMI_SCDC_RSED_UPDATE_MARK (1 << 6)
/*
* see HDMI2.1 section 10.4.1.4.
* All Configuration fields are readable and writable.
*/
union HdmiScdcsTmdsConfig {
uint8_t data;
struct {
uint8_t scramblingEnable : 1;
uint8_t tmdsBitClockRatio: 1; /*
* 0: TMDS_Bit_Period/TMDS_Clock_Period is 1/10;
* 1: TMDS_Bit_Period/TMDS_Clock_Period is 1/40.
*/
uint8_t reserved : 6;
} bits;
};
/*
* see HDMI2.1 section 10.4.1.5.
* The Status Flags are all Read Only.
*/
union HdmiScdcsScramblerStatus {
uint8_t data;
struct {
uint8_t scramblingStatus : 1;
uint8_t reserved : 7;
} bits;
};
/*
* see hdmi2.0 spec table 10-21.
* All Configuration fields are readable and writable.
*/
union HdmiScdcsConfig0 {
uint8_t data;
struct {
uint8_t rrEnable : 1; /*
* The source set this bit when the source supports Read Request.
* The sink shall reset this bit when SCDC of the sink goes from the disabled to enabled.
*/
uint8_t fltNoRetrain : 1;
uint8_t reserved : 6;
} bits;
};
/*
* see HDMI2.1 section 10.4.1.6.
*/
union HdmiScdcsConfig1 {
uint8_t data;
struct {
uint8_t frlRate : 4; /*
* Source select the FRL rate and Lane count by writing into this register.
* This field is written by the Source during the Link Training protocol.
*/
uint8_t ffeLevels : 4;
} bits;
};
/*
* see HDMI2.1 section 10.4.1.6.
*/
union HdmiScdcsTestConfig1 {
uint8_t data;
struct {
uint8_t reserved0 : 1;
uint8_t preShootIOnly : 1;
uint8_t deEmphasisOnly : 1;
uint8_t noFfe : 1;
uint8_t reserved1 : 1;
uint8_t fltNoTimeout : 1;
uint8_t dscFrlMax : 1;
uint8_t frlMax : 1;
} bits;
};
#define HDMI_SCDC_PRE_SHOOT_ONLY_MARK (1 << 1)
#define HDMI_SCDC_DE_EMPHASIS_ONLY_MARK (1 << 2)
#define HDMI_SCDC_NO_FFE_MARK (1 << 3)
#define HDMI_SCDC_FLT_NO_TIMEOUT_MARK (1 << 5)
#define HDMI_SCDC_DSC_FRL_MAX_MARK (1 << 6)
#define HDMI_SCDC_FRL_MAX_MARK (1 << 7)
/*
* see HDMI2.1 section 10.4.1.7.
* The Status Flags are all Read Only.
*/
union HdmiScdcsStatusFlag0 {
uint8_t data;
struct {
uint8_t clockDetected : 1; /* This bit shall be set by the sink when the sink detects a valid clock signal. */
uint8_t ch0Locked : 1; /*
* This bit shall be set by the sink when the sink is successfully decoding
* data on HDMI Channel 0.
*/
uint8_t ch1Locked : 1; /*
* This bit shall be set by the sink when the sink is successfully decoding
* data on HDMI Channel 1.
*/
uint8_t ch2Locked : 1; /*
* This bit shall be set by the sink when the sink is successfully decoding
* data on HDMI Channel 2.
*/
uint8_t ch3Locked : 1;
uint8_t reserved : 1;
uint8_t fltReady : 1;
uint8_t dscDecodeFail : 1;
} bits;
};
#define HDMI_SCDC_CLOCK_DETECTED_MARK (1 << 0)
#define HDMI_SCDC_CH0_LOCKED_MARK (1 << 1)
#define HDMI_SCDC_CH1_LOCKED_MARK (1 << 2)
#define HDMI_SCDC_CH2_LOCKED_MARK (1 << 3)
#define HDMI_SCDC_CH3_LOCKED_MARK (1 << 4)
#define HDMI_SCDC_FLT_READY_MARK (1 << 6)
#define HDMI_SCDC_DSC_DECODE_FAIL_MARK (1 << 7)
/*
* see HDMI2.1 section 10.4.1.7.
* The Status Flags are all Read Only.
*/
union HdmiScdcsStatusFlag1 {
uint8_t data;
struct {
uint8_t ln0LtpReq : 4;
uint8_t ln1LtpReq : 4;
} bits;
};
/*
* see HDMI2.1 section 10.4.1.7.
* The Status Flags are all Read Only.
*/
union HdmiScdcsStatusFlag2 {
uint8_t data;
struct {
uint8_t ln2LtpReq : 4;
uint8_t ln3LtpReq : 4;
} bits;
};
/*
* see hdmi2.0 spec table 10-23. Offeset 0x50~0x55.
* The Character Error Detection counters are not writable by the source and are cleared on read by the source.
*/
union HdmiScdcsCharacterErrorDetection {
uint16_t data;
struct {
uint16_t chErrCntLower : 8; /* Channel 0/1/2 Erroe Count bits 7->0 */
uint16_t chErrCntUpper : 7; /* Channel 0/1/2 Erroe Count bits 14->8 */
uint16_t chValid : 1; /* Channel 0/1/2 valid flag */
} bits;
};
/*
* see hdmi2.0 spec table 10-24.
* The Test Configuration registers are privided to facilitate compliance testing.
*/
union HdmiScdcsTestConfig0 {
uint8_t data;
struct {
uint8_t testReadRequestDelay : 7;
uint8_t testReadRequest : 1; /* Read/Write */
} bits;
};
struct HdmiScdcsRegStatus {
uint8_t sinkVersion;
uint8_t sourceVersion; /* R/W */
union HdmiScdcsUpdateFlag0 upfate0; /* R/W */
union HdmiScdcsTmdsConfig tmdsCfg; /* R/W */
union HdmiScdcsScramblerStatus scramblerStatus;
union HdmiScdcsConfig0 cfg0; /* R/W */
union HdmiScdcsStatusFlag0 statusFlag0;
union HdmiScdcsCharacterErrorDetection errDet0;
union HdmiScdcsCharacterErrorDetection errDet1;
union HdmiScdcsCharacterErrorDetection errDet2;
uint8_t errDetChecksum;
union HdmiScdcsTestConfig0 testCfg0; /* R/W */
uint8_t ieeeOui[HDMI_SCDCS_OFFSET_IEEE_OUI_1ST - HDMI_SCDCS_OFFSET_IEEE_OUI_3TH + 1];
uint8_t deviceId[HDMI_SCDCS_OFFSET_DEVICE_ID_END - HDMI_SCDCS_OFFSET_DEVICE_ID_START + 1];
};
struct HdmiScdcScrambleCap {
bool sinkScramble;
bool sourceScramble;
bool tmdsBitClockRatio40;
};
struct HdmiScdcAttribute {
bool sinkReadRequest;
bool srcScramble;
bool sinkScramble;
bool tmdsBitClockRatio40;
uint32_t ScrambleTimeOut;
uint32_t ScrambleInterval;
};
struct HdmiScdc {
struct HdmiScdcsRegStatus status;
struct HdmiScdcAttribute attr;
void *priv;
};
/* used for frl. */
enum HdmiScdcOptMsg {
HDMI_SCDC_OPT_SET_SOURCE_VER = 0,
HDMI_SCDC_OPT_GET_SOURCE_VER = 1,
HDMI_SCDC_OPT_GET_SINK_VER = 2,
HDMI_SCDC_OPT_SET_FLT_UPDATE = 3,
HDMI_SCDC_OPT_GET_FLT_UPDATE = 4,
HDMI_SCDC_OPT_SET_FRL_START = 5,
HDMI_SCDC_OPT_GET_FRL_START = 6,
HDMI_SCDC_OPT_SET_CONFIG1 = 7,
HDMI_SCDC_OPT_GET_CONFIG1 = 8,
HDMI_SCDC_OPT_GET_TEST_CONFIG_1 = 9,
HDMI_SCDC_OPT_GET_FLT_READY = 10,
HDMI_SCDC_OPT_GET_LTP_REQ = 11,
HDMI_SCDC_OPT_BUTT,
};
int32_t HdmiScdcScrambleSet(struct HdmiScdc *scdc, struct HdmiScdcScrambleCap *scramble);
int32_t HdmiScdcScrambleGet(struct HdmiScdc *scdc, struct HdmiScdcScrambleCap *scramble);
bool HdmiScdcSinkSupport(struct HdmiScdc *scdc);
void HdmiScdcReset(struct HdmiScdc *scdc);
int32_t HdmiScdcOptMsgHandle(struct HdmiScdc *scdc, enum HdmiScdcOptMsg msg, uint8_t *buffer, uint32_t len);
int32_t HdmiScdcFillScrambleCap(struct HdmiScdc *scdc, struct HdmiScdcScrambleCap *scramble,
enum HdmiTmdsModeType *tmdsMode);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* HDMI_SCDC_H */
File diff suppressed because it is too large Load Diff
+345
View File
@@ -0,0 +1,345 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "hdf_log.h"
#include "hdmi_common.h"
#define HDF_LOG_TAG hdmi_common_c
/*
* vic, pixel clk, vfreq, hactive, vactive, hblank, vblank, hfront, hsync, hback, vfront, vsync, vback, aspect,
* timing, I/P
*/
struct HdmiVideoDefInfo g_ceaVideoDefInfoMap[HDMI_CEA_VIDEO_CODE_MAX] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
HDMI_PICTURE_ASPECT_NO_DATA, HDMI_VIDEO_TIMING_NONE, HDMI_VIDEO_FORMAT_NULL },
{ HDMI_VIC_640X480P60_4_3, 25175, 59940, 640, 480, 160, 45, 16, 96, 48, 10, 2, 33,
HDMI_PICTURE_ASPECT_4_3, HDMI_VIDEO_TIMING_640X480P60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_720X480P60_4_3, 27000, 59940, 720, 480, 138, 45, 16, 62, 60, 9, 6, 30,
HDMI_PICTURE_ASPECT_4_3, HDMI_VIDEO_TIMING_720X480P60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_720X480P60_16_9, 27000, 59940, 720, 480, 138, 45, 16, 62, 60, 9, 6, 30,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_720X480P60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_1280X720P60_16_9, 74250, 60000, 1280, 720, 370, 30, 110, 40, 220, 5, 5, 20,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1280X720P60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_1920X1080I60_16_9, 74250, 60000, 1920, 1080, 280, 22, 88, 44, 148, 2, 5, 15,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1920X1080I60, HDMI_VIDEO_FORMA_INTERLACE },
{ HDMI_VIC_1440X480I60_4_3, 27000, 59940, 1440, 480, 276, 22, 38, 124, 114, 4, 3, 15,
HDMI_PICTURE_ASPECT_4_3, HDMI_VIDEO_TIMING_1440X480I60, HDMI_VIDEO_FORMA_INTERLACE },
{ HDMI_VIC_1440X480I60_16_9, 27000, 59940, 1440, 480, 276, 22, 38, 124, 114, 4, 3, 15,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1440X480I60, HDMI_VIDEO_FORMA_INTERLACE },
{ HDMI_VIC_1440X240P60_4_3, 27000, 60054, 1440, 240, 276, 22, 38, 124, 114, 4, 3, 15,
HDMI_PICTURE_ASPECT_4_3, HDMI_VIDEO_TIMING_1440X240P60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_1440X240P60_16_9, 27000, 60054, 1440, 240, 276, 22, 38, 124, 114, 4, 3, 15,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1440X240P60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_2880X480I60_4_3, 54000, 59940, 2880, 480, 552, 22, 76, 248, 228, 4, 3, 15,
HDMI_PICTURE_ASPECT_4_3, HDMI_VIDEO_TIMING_2880X480I60, HDMI_VIDEO_FORMA_INTERLACE },
{ HDMI_VIC_2880X480I60_16_9, 54000, 59940, 2880, 480, 552, 22, 76, 248, 228, 4, 3, 15,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_2880X480I60, HDMI_VIDEO_FORMA_INTERLACE },
{ HDMI_VIC_2880X240P60_4_3, 54000, 60054, 2880, 240, 552, 22, 76, 248, 228, 4, 3, 15,
HDMI_PICTURE_ASPECT_4_3, HDMI_VIDEO_TIMING_2880X240I60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_2880X240P60_16_9, 54000, 60054, 2880, 240, 552, 23, 76, 248, 228, 4, 3, 15,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_2880X240I60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_1440X480P60_4_3, 54000, 59940, 1440, 480, 276, 45, 32, 124, 120, 9, 6, 30,
HDMI_PICTURE_ASPECT_4_3, HDMI_VIDEO_TIMING_1440X480P60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_1440X480P60_16_9, 54000, 59940, 1440, 480, 276, 45, 32, 124, 120, 9, 6, 30,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1440X480P60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_1920X1080P60_16_9, 148500, 60000, 1920, 1080, 280, 45, 88, 44, 148, 4, 5, 36,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1920X1080P60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_720X576P50_4_3, 27000, 50000, 720, 576, 144, 49, 12, 64, 68, 5, 5, 39,
HDMI_PICTURE_ASPECT_4_3, HDMI_VIDEO_TIMING_720X576P50, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_720X576P50_16_9, 27000, 50000, 720, 576, 144, 49, 12, 64, 68, 5, 5, 39,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_720X576P50, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_1280X720P50_16_9, 74250, 50000, 1280, 720, 700, 30, 440, 40, 220, 5, 5, 20,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1280X720P50, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_1920X1080I50_16_9, 74250, 50000, 1920, 1080, 720, 24, 528, 44, 148, 2, 5, 15,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1920X1080I50, HDMI_VIDEO_FORMA_INTERLACE },
{ HDMI_VIC_1440X576I50_4_3, 27000, 50000, 1440, 576, 288, 24, 24, 126, 138, 2, 3, 19,
HDMI_PICTURE_ASPECT_4_3, HDMI_VIDEO_TIMING_1440X576I50, HDMI_VIDEO_FORMA_INTERLACE },
{ HDMI_VIC_1440X576I50_16_9, 27000, 50000, 1440, 576, 288, 24, 24, 126, 138, 2, 3, 19,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1440X576I50, HDMI_VIDEO_FORMA_INTERLACE },
{ HDMI_VIC_1440X576P50_4_3, 54000, 50000, 1440, 576, 288, 49, 24, 128, 136, 5, 5, 39,
HDMI_PICTURE_ASPECT_4_3, HDMI_VIDEO_TIMING_1440X576P50, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_1440X576P50_16_9, 54000, 50000, 1440, 576, 288, 49, 24, 128, 136, 5, 5, 39,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1440X576P50, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_1920X1080P50_16_9, 148500, 50000, 1920, 1080, 720, 45, 528, 44, 148, 4, 5, 36,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1920X1080P50, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_1920X1080P24_16_9, 742500, 24000, 1920, 1080, 830, 45, 638, 44, 148, 4, 5, 36,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1920X1080P24, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_1920X1080P25_16_9, 742500, 25000, 1920, 1080, 720, 45, 528, 44, 148, 4, 5, 36,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1920X1080P25, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_1920X1080P30_16_9, 742500, 30000, 1920, 1080, 280, 45, 88, 44, 148, 4, 5, 36,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1920X1080P30, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_3840X2160P24_16_9, 297000, 24000, 3840, 2160, 1660, 90, 1276, 88, 296, 8, 10, 72,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_3840X2160P24, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_3840X2160P25_16_9, 297000, 25000, 3840, 2160, 1440, 90, 1056, 88, 296, 8, 10, 72,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_3840X2160P25, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_3840X2160P30_16_9, 297000, 30000, 3840, 2160, 560, 90, 176, 88, 296, 8, 10, 72,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_3840X2160P30, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_3840X2160P50_16_9, 594000, 50000, 3840, 2160, 1440, 90, 1056, 88, 296, 8, 10, 72,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_3840X2160P50, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_3840X2160P60_16_9, 594000, 60000, 3840, 2160, 560, 90, 176, 88, 296, 8, 10, 72,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_3840X2160P60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_4096X2160P24_256_135, 297000, 24000, 4096, 2160, 1404, 90, 1020, 88, 296, 8, 10, 72,
HDMI_PICTURE_ASPECT_256_135, HDMI_VIDEO_TIMING_4096X2160P24, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_4096X2160P25_256_135, 297000, 25000, 4096, 2160, 1184, 90, 968, 88, 128, 8, 10, 72,
HDMI_PICTURE_ASPECT_256_135, HDMI_VIDEO_TIMING_4096X2160P25, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_4096X2160P30_256_135, 297000, 30000, 4096, 2160, 304, 90, 88, 88, 128, 8, 10, 72,
HDMI_PICTURE_ASPECT_256_135, HDMI_VIDEO_TIMING_4096X2160P30, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_4096X2160P50_256_135, 594000, 50000, 4096, 2160, 1184, 90, 968, 88, 128, 8, 10, 72,
HDMI_PICTURE_ASPECT_256_135, HDMI_VIDEO_TIMING_4096X2160P50, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_4096X2160P60_256_135, 594000, 60000, 4096, 2160, 304, 90, 88, 88, 128, 8, 10, 72,
HDMI_PICTURE_ASPECT_256_135, HDMI_VIDEO_TIMING_4096X2160P60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_3840X2160P120_16_9, 1188000, 120000, 3840, 2160, 560, 90, 176, 88, 296, 8, 10, 72,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_3840X2160P120, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_7680X4320P24_16_9, 1188000, 24000, 7680, 4320, 3320, 180, 2552, 176, 592, 16, 20, 144,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_7680X4320P24, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_7680X4320P25_16_9, 1188000, 25000, 7680, 4320, 3120, 80, 2352, 176, 592, 16, 20, 44,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_7680X4320P25, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_7680X4320P30_16_9, 1188000, 30000, 7680, 4320, 1320, 80, 552, 176, 592, 16, 20, 44,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_7680X4320P30, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_VIC_4096X2160P120_256_135, 1188000, 120000, 4096, 2160, 304, 90, 88, 88, 128, 8, 10, 72,
HDMI_PICTURE_ASPECT_256_135, HDMI_VIDEO_TIMING_4096X2160P120, HDMI_VIDEO_FORMAT_PROGRESSIVE }
};
struct HdmiVideoDefInfo g_vesaVideoDefInfoMap[HDMI_VESA_VIDEO_CODE_MAX] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, HDMI_PICTURE_ASPECT_NO_DATA,
HDMI_VIDEO_TIMING_NONE, HDMI_VIDEO_FORMAT_NULL },
{ 0, 40000, 60317, 800, 600, 256, 28, 40, 128, 88, 1, 4, 23, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_800X600_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 33750, 60000, 848, 480, 240, 37, 16, 112, 112, 6, 8, 23, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_848X480_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 65000, 60004, 1024, 768, 320, 38, 24, 136, 160, 3, 6, 29, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1024X768_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 74250, 60000, 1280, 720, 370, 30, 110, 40, 220, 5, 5, 20, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1280X720_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 68250, 59995, 1280, 768, 160, 22, 48, 32, 80, 3, 7, 12, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1280X768_60_RB, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 79500, 59870, 1280, 768, 384, 30, 64, 128, 192, 3, 7, 20, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1280X768_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 71001, 59910, 1280, 800, 160, 23, 48, 32, 80, 3, 6, 14, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1280X800_60_RB, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 83500, 59810, 1280, 800, 400, 31, 72, 128, 200, 3, 6, 22, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1280X800_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 108000, 60000, 1280, 960, 520, 40, 96, 112, 312, 1, 3, 36, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1280X960_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 108000, 60020, 1280, 1024, 408, 42, 48, 112, 248, 1, 3, 38, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1280X1024_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 85500, 60015, 1360, 768, 432, 27, 64, 112, 256, 3, 6, 18, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1360X768_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 85501, 59790, 1366, 768, 426, 30, 70, 143, 213, 3, 3, 24, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1366X768_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 121749, 59978, 1400, 1050, 464, 39, 88, 144, 232, 3, 4, 32, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1400X1050_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 88749, 59901, 1440, 900, 160, 26, 48, 32, 80, 3, 6, 17, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1440X900_60_RB, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 106499, 59887, 1440, 900, 464, 34, 80, 152, 232, 3, 6, 25, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1440X900_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 108000, 60000, 1440, 1050, 144, 49, 12, 64, 68, 3, 6, 25, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1440X1050_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 108000, 60000, 1440, 1050, 144, 49, 12, 64, 68, 3, 6, 25, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1440X1050_60_RB, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 108000, 60000, 1600, 900, 200, 100, 24, 80, 96, 1, 3, 96, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1600X900_60_RB, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 162000, 60000, 1600, 1200, 560, 50, 64, 192, 304, 1, 3, 46, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1600X1200_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 118999, 59883, 1680, 1050, 160, 30, 48, 32, 80, 3, 6, 21, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1680X1050_60_RB, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 146249, 59954, 1680, 1050, 560, 39, 104, 176, 280, 3, 6, 30, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1680X1050_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 204751, 60000, 1792, 1344, 656, 50, 128, 200, 328, 1, 3, 46, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1792X1344_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 218249, 59995, 1856, 1392, 672, 47, 96, 224, 352, 1, 3, 43, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1856X1392_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 148500, 60000, 1920, 1080, 280, 45, 88, 44, 148, 4, 5, 36, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1920X1080_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 154000, 59950, 1920, 1200, 160, 35, 48, 32, 80, 3, 6, 26, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1920X1200_60_RB, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 193251, 59885, 1920, 1200, 672, 45, 136, 200, 336, 3, 6, 36, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1920X1200_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 234000, 60000, 1920, 1440, 680, 60, 128, 208, 344, 1, 3, 56, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_1920X1440_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 162000, 60000, 2048, 1152, 202, 48, 26, 80, 96, 1, 3, 44, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_2048X1152_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 82500, 50000, 2560, 1440, 520, 30, 260, 40, 220, 3, 3, 24, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_2560X1440_60_RB, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ 0, 348502, 59987, 2560, 1600, 944, 58, 192, 280, 472, 3, 6, 49, HDMI_PICTURE_ASPECT_16_9,
HDMI_VIDEO_TIMING_VESA_2560X1600_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
};
struct HdmiVideo4kInfo g_video4kInfoMap[HDMI_VIDEO_4K_CODES_MAX] = {
{ HDMI_4K_VIC_3840X2160_30, HDMI_VIC_3840X2160P30_16_9, 296703, 30, 3840, 2160,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_3840X2160P30, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_4K_VIC_3840X2160_25, HDMI_VIC_3840X2160P25_16_9, 297000, 25, 3840, 2160,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_3840X2160P25, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_4K_VIC_3840X2160_24, HDMI_VIC_3840X2160P24_16_9, 296703, 24, 3840, 2160,
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_3840X2160P24, HDMI_VIDEO_FORMAT_PROGRESSIVE },
{ HDMI_4K_VIC_4096X2160_24, HDMI_VIC_4096X2160P24_256_135, 297000, 24, 4096, 2160,
HDMI_PICTURE_ASPECT_256_135, HDMI_VIDEO_TIMING_4096X2160P24, HDMI_VIDEO_FORMAT_PROGRESSIVE }
};
enum HdmiVideoBitDepth HdmiCommonDeepClolorConvertToColorDepth(enum HdmiDeepColor deepColor)
{
enum HdmiVideoBitDepth colorDepth;
switch (deepColor) {
case HDMI_DEEP_COLOR_24BITS :
colorDepth = HDMI_VIDEO_BIT_DEPTH_8;
break;
case HDMI_DEEP_COLOR_30BITS :
colorDepth = HDMI_VIDEO_BIT_DEPTH_10;
break;
case HDMI_DEEP_COLOR_36BITS :
colorDepth = HDMI_VIDEO_BIT_DEPTH_12;
break;
case HDMI_DEEP_COLOR_48BITS :
colorDepth = HDMI_VIDEO_BIT_DEPTH_16;
break;
default :
HDF_LOGD("deep color %d is not support, use default value.", deepColor);
colorDepth = HDMI_VIDEO_BIT_DEPTH_8;
break;
}
return colorDepth;
}
enum HdmiDeepColor HdmiCommonColorDepthConvertToDeepClolor(enum HdmiVideoBitDepth colorDepth)
{
enum HdmiDeepColor deepColor;
switch (colorDepth) {
case HDMI_VIDEO_BIT_DEPTH_8 :
deepColor = HDMI_DEEP_COLOR_24BITS;
break;
case HDMI_VIDEO_BIT_DEPTH_10 :
deepColor = HDMI_DEEP_COLOR_30BITS;
break;
case HDMI_VIDEO_BIT_DEPTH_12 :
deepColor = HDMI_DEEP_COLOR_36BITS;
break;
case HDMI_VIDEO_BIT_DEPTH_16 :
deepColor = HDMI_DEEP_COLOR_48BITS;
break;
case HDMI_VIDEO_BIT_DEPTH_OFF :
deepColor = HDMI_DEEP_COLOR_OFF;
break;
default :
deepColor = HDMI_DEEP_COLOR_BUTT;
break;
}
return deepColor;
}
enum HdmiVic HdmiCommonGetVic(enum HdmiVideoTiming timing,
enum HdmiPictureAspectRatio aspect, bool enable3d)
{
uint32_t i, len;
enum HdmiVic vic = 0;
len = sizeof(g_ceaVideoDefInfoMap) / sizeof(g_ceaVideoDefInfoMap[0]);
for (i = 0; i < len; i++) {
if (timing == g_ceaVideoDefInfoMap[i].timing && aspect == g_ceaVideoDefInfoMap[i].aspect) {
vic = g_ceaVideoDefInfoMap[i].vic;
break;
}
}
if (enable3d == true) {
/* see hdmi spec 10.2. */
if (vic == HDMI_VIC_3840X2160P24_16_9 || vic == HDMI_VIC_3840X2160P25_16_9 ||
vic == HDMI_VIC_3840X2160P30_16_9 || vic == HDMI_VIC_4096X2160P24_256_135) {
HDF_LOGI("4k x 2k 2D vic:%d.", vic);
vic = HDMI_VIC_NONE;
}
}
return vic;
}
static struct HdmiVideoDefInfo *HdmiCommonGetCommFormatInfo(enum HdmiVic vic)
{
uint32_t i, len;
len = sizeof(g_ceaVideoDefInfoMap) / sizeof(g_ceaVideoDefInfoMap[0]);
for (i = 0; i < len; i++) {
if (vic == g_ceaVideoDefInfoMap[i].vic) {
return &g_ceaVideoDefInfoMap[i];
}
}
return NULL;
}
static struct HdmiVideoDefInfo *HdmiCommonGetVesaFormatInfo(enum HdmiVideoTiming timing)
{
uint32_t i, len;
len = sizeof(g_vesaVideoDefInfoMap) / sizeof(g_vesaVideoDefInfoMap[0]);
for (i = 0; i < len; i++) {
if (timing == g_vesaVideoDefInfoMap[i].timing) {
return &g_vesaVideoDefInfoMap[i];
}
}
return NULL;
}
struct HdmiVideoDefInfo *HdmiCommonGetVideoDefInfo(enum HdmiVideoTiming timing,
enum HdmiPictureAspectRatio aspect, bool enable3d)
{
enum HdmiVic vic;
struct HdmiVideoDefInfo *info = NULL;
if (timing < HDMI_VIDEO_TIMING_VESA_DEFINE) {
vic = HdmiCommonGetVic(timing, aspect, enable3d);
info = HdmiCommonGetCommFormatInfo(vic);
} else if (timing < HDMI_VIDEO_TIMING_USER_DEFINE) {
info = HdmiCommonGetVesaFormatInfo(timing);
}
return info;
}
enum HdmiVideoTiming HdmiCommonGetVideoTiming(enum HdmiVic vic, enum HdmiPictureAspectRatio aspect)
{
uint32_t i, len;
enum HdmiVideoTiming timing = HDMI_VIDEO_TIMING_NONE;
len = sizeof(g_ceaVideoDefInfoMap) / sizeof(g_ceaVideoDefInfoMap[0]);
for (i = 0; i < len; i++) {
if (vic == g_ceaVideoDefInfoMap[i].vic && aspect == g_ceaVideoDefInfoMap[i].aspect) {
timing = g_ceaVideoDefInfoMap[i].timing;
break;
}
}
return timing;
}
struct HdmiVideo4kInfo *HdmiCommonGetVideo4kInfo(uint32_t _4kVic)
{
uint32_t i, len;
len = sizeof(g_video4kInfoMap) / sizeof(g_video4kInfoMap[0]);
for (i = 0; i < len; i++) {
if (_4kVic == g_video4kInfoMap[i]._4kVic) {
return &g_video4kInfoMap[i];
}
}
HDF_LOGD("4k not support vic = %u", _4kVic);
return NULL;
}
enum HdmiVideoTiming HdmiCommonGetVideo4kTiming(uint32_t _4kVic)
{
uint32_t i, len;
enum HdmiVideoTiming timing = HDMI_VIDEO_TIMING_NONE;
len = sizeof(g_video4kInfoMap) / sizeof(g_video4kInfoMap[0]);
for (i = 0; i < len; i++) {
if (_4kVic == g_video4kInfoMap[i]._4kVic) {
timing = g_video4kInfoMap[i].timing;
break;
}
}
return timing;
}
File diff suppressed because it is too large Load Diff
+45
View File
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "hdmi_core.h"
#define HDF_LOG_TAG hdmi_ddc_c
int32_t HdmiCntlrDdcTransfer(struct HdmiCntlr *cntlr, struct HdmiDdcCfg *ddcCfg)
{
int32_t ret;
if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->ddcTransfer == NULL) {
return HDF_ERR_INVALID_OBJECT;
}
if (ddcCfg == NULL) {
return HDF_ERR_INVALID_PARAM;
}
HdmiCntlrLock(cntlr);
ret = cntlr->ops->ddcTransfer(cntlr, ddcCfg);
HdmiCntlrUnlock(cntlr);
return ret;
}
int32_t HdmiDdcTransfer(struct HdmiDdc *ddc, struct HdmiDdcCfg *cfg)
{
int32_t ret;
if (ddc == NULL || cfg == NULL) {
return HDF_ERR_INVALID_PARAM;
}
if (cfg->mode >= HDMI_DDC_MODE_BUTT) {
return HDF_ERR_INVALID_PARAM;
}
(void)OsalMutexLock(&(ddc->ddcMutex));
ret = HdmiCntlrDdcTransfer(ddc->priv, cfg);
(void)OsalMutexUnlock(&(ddc->ddcMutex));
return ret;
}
+279
View File
@@ -0,0 +1,279 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "hdf_log.h"
#include "hdmi_common.h"
#include "hdmi_dfm.h"
#define HDF_LOG_TAG hdmi_dfm_c
#define HDMI_DFM_THOUSAND 1000
#define HDMI_DFM_INVALID_VAL (-1)
uint32_t HdmiDfmGetPixelFormat(enum HdmiColorSpace colorSpace)
{
uint32_t pixelFormat;
switch (colorSpace) {
case HDMI_COLOR_SPACE_RGB :
pixelFormat = HDMI_DFM_PIXEL_FORMAT_MODE_0;
break;
case HDMI_COLOR_SPACE_YCBCR420 :
pixelFormat = HDMI_DFM_PIXEL_FORMAT_MODE_1;
break;
case HDMI_COLOR_SPACE_YCBCR422 :
pixelFormat = HDMI_DFM_PIXEL_FORMAT_MODE_2;
break;
case HDMI_COLOR_SPACE_YCBCR444 :
pixelFormat = HDMI_DFM_PIXEL_FORMAT_MODE_3;
break;
default :
pixelFormat = HDMI_DFM_PIXEL_FORMAT_MODE_0;
break;
}
return pixelFormat;
}
void HdmiDfmFillParam(struct HdmiDfmParam *param, struct HdmiVideoDefInfo *videoInfo,
struct HdmiAudioAttr *audioAttr, enum HdmiColorSpace colorSpace, enum HdmiDeepColor deepColor)
{
if (param == NULL || videoInfo == NULL || audioAttr == NULL) {
return;
}
param->hactive = videoInfo->hactive;
param->vactive = videoInfo->vactive;
param->hblank = videoInfo->hblank;
param->vblank = videoInfo->vblank;
param->hsync = videoInfo->hsync;
param->hback = videoInfo->hback;
param->hfront = videoInfo->hfront;
param->vsync = videoInfo->vsync;
param->vback = videoInfo->vback;
param->vfront = videoInfo->vfront;
param->vfreq = videoInfo->rate;
param->colorDepth = HdmiCommonDeepClolorConvertToColorDepth(deepColor);
param->pixelFormat = HdmiDfmGetPixelFormat(colorSpace);
param->audioRate = (uint32_t)audioAttr->sampleRate;
param->layout = (audioAttr->channels > HDMI_AUDIO_FORMAT_CHANNEL_2) ? true : false;
/* ACAT packet_type */
param->acat = HDMI_AUDIO_CHANNEL_ALLOC_TYPE3;
param->packetType = HDMI_AUDIO_SAMPLE_PACKET;
}
static void HdmiDfmBaseInfoInit(struct HdmiDfmInfo *info, struct HdmiDfmParam *param)
{
info->htotal = param->hactive + param->hblank;
info->vtotal = param->vactive + param->vblank;
info->pixelClk = (uint64_t)(info->htotal) * info->vtotal * param->vfreq / HDMI_DFM_THOUSAND;
/* 1. Determine the maximum legal pixel rate. */
info->maxPixelClk = info->pixelClk * (HDMI_DFM_THOUSAND + HDMI_DFM_FRL_PIXELCLK_TOLERANCE) / HDMI_DFM_THOUSAND;
info->minPixelClk = info->pixelClk * (HDMI_DFM_THOUSAND - HDMI_DFM_FRL_PIXELCLK_TOLERANCE) / HDMI_DFM_THOUSAND;
if (info->maxPixelClk == 0 || info->minPixelClk == 0) {
HDF_LOGE("max or min pixel clock is 0!");
return;
}
/* 2. Determine the minimum Video Line period. */
info->lineMinTime = (uint64_t)info->htotal * 1000000000000 / info->maxPixelClk;
info->lineMaxTime = (uint64_t)info->htotal * 1000000000000 / info->minPixelClk;
/* 3. Determine the Worst Case Slow Bit Rate. x10000 */
info->minBitRate = (uint64_t)param->bitRate * 1000000000 * (10000 - HDMI_DFM_FRL_BITRATE_TOLERANCE) / 10000;
info->maxBitRate = (uint64_t)param->bitRate * 1000000000 * (10000 + HDMI_DFM_FRL_BITRATE_TOLERANCE) / 10000;
/* 4. Determine the FRL Character Rate */
info->minFrlCharRate = info->minBitRate / 18;
info->maxFrlCharRate = info->maxBitRate / 18;
/* 5. Determine the Total FRL Characters per line Period. */
info->minFrlCharsPerLine = (uint32_t)(info->lineMinTime * info->minFrlCharRate * param->laneNum / 1000000000000);
info->maxFrlCharsPerLine = (uint32_t)(info->lineMaxTime * info->maxFrlCharRate * param->laneNum / 1000000000000);
info->cFrlSb = HDMI_DFM_FRL_SB_LEN(param->laneNum);
info->overheadSb = param->laneNum * 100000 / info->cFrlSb;
info->overheadRs = HDMI_DFM_RS_NUM_PER_CB * HDMI_DFM_FRL_CB_NUM_PER_SB * 100000 / info->cFrlSb;
info->overheadMap = 25 * 10000 / info->cFrlSb; /* FRL map chars per blk. */
info->overheadMin = info->overheadSb + info->overheadRs + info->overheadMap;
info->overheadMax = info->overheadMin + HDMI_DFM_OVERHEAD_SIZE;
}
static uint32_t HdmiDfmGetAudioPackets(struct HdmiDfmParam *param)
{
uint32_t ap = 0;
switch (param->packetType) {
case HDMI_AUDIO_SAMPLE_PACKET :
case HDMI_ONE_BIT_AUDIO_SAMPLE_PACKET :
ap = HDMI_AUDIO_AP_SIZE_100;
if (param->layout == false) {
ap = HDMI_AUDIO_AP_SIZE_25;
}
break;
case HDMI_DTS_AUDIO_PACKET :
case HDMI_HBR_AUDIO_PACKET :
case HDMI_MULTI_STREAM_AUDIO_SAMPLE_PACKET :
case HDMI_ONE_BIT_MULTI_STREAM_AUDIO_SAMPLE_PACKET :
ap = HDMI_AUDIO_AP_SIZE_100;
break;
case HDMI_AUDIO_3D_SAMPLE_PACKET :
case HDMI_ONE_BIT_AUDIO_3D_SAMPLE_PACKET :
if (param->acat == HDMI_AUDIO_CHANNEL_ALLOC_TYPE1) {
ap = HDMI_AUDIO_AP_SIZE_200;
} else if (param->acat == HDMI_AUDIO_CHANNEL_ALLOC_TYPE2) {
ap = HDMI_AUDIO_AP_SIZE_300;
} else if (param->acat == HDMI_AUDIO_CHANNEL_ALLOC_TYPE3) {
ap = HDMI_AUDIO_AP_SIZE_400;
}
break;
default :
HDF_LOGE("audio packet type 0x%x, is not support.", param->packetType);
break;
}
return ap;
}
static void HdmiDfmCaculateAudioInfo(struct HdmiDfmInfo *info, struct HdmiDfmParam *param)
{
/* 1. Determine the number of audio packets required to carry each sample. */
info->audioAp = HdmiDfmGetAudioPackets(param);
/* 2. Determine Average Audio Related Packet Rate. */
info->audioRap = (uint32_t)((uint64_t)param->audioRate * (1000 + HDMI_DFM_FRL_AUDIOCLK_TOLERANCE) *
info->audioAp / 100000);
/* 3. Determine Average Required Packets per line. */
info->avgAudioPacketsPerLine = (uint32_t)((uint64_t)info->audioRap * info->lineMinTime / 1000000000);
/* 4. Determine the Packets per Hblank that must be supportable. */
info->audioPacketsLine = (info->avgAudioPacketsPerLine + HDMI_DFM_THOUSAND - 1) / HDMI_DFM_THOUSAND;
/*
* 5. Determine The c_frl_blank_min(64(guard bands, two 12-character control periods, c_frl_active_extra)
* and 32 audio_packets).
*/
info->hblankAudioMin = 64 + 32 * info->audioPacketsLine;
}
static void HdmiDfmCaculateVideoBorrowInfo(struct HdmiDfmInfo *info)
{
if (info->activeTimeRef >= info->activeTimeMin && info->blankTimeRef >= info->blankTimeMin) {
info->tBorrow = 0;
} else if (info->activeTimeRef < info->activeTimeMin && info->blankTimeRef >= info->blankTimeMin) {
info->tBorrow = info->activeTimeMin - info->activeTimeRef;
} else {
info->tBorrow = HDMI_DFM_INVALID_VAL;
}
if (info->tBorrow == HDMI_DFM_INVALID_VAL) {
info->tbBorrow = HDMI_DFM_INVALID_VAL;
} else {
info->tbBorrow = ((int32_t)(info->tBorrow * info->avgTbRate / 100000000000) + 10 - 1) / 10;
}
}
static void HdmiDfmCaculateVideoInfo(struct HdmiDfmInfo *info, struct HdmiDfmParam *param)
{
uint32_t kcd, k420;
/*
* 1. if 4:2:2 pixels, kcd is 1. Otherwise, kcd is CD / 8.
* if 4:2:0 pixels, k420 is 2. Otherwise, k420 is 1.
*/
kcd = (param->pixelFormat == 2) ? HDMI_DFM_MAGNIFICATION_8 : param->colorDepth;
k420 = (param->pixelFormat == 1) ? 2 : 1;
/* 2. Determine Bits per Pixel */
info->bpp = ((24 * kcd) / k420) / HDMI_DFM_MAGNIFICATION_8;
/* 3. Determine Video Bytes per line. */
info->activeBytesPerLine = info->bpp * param->hactive / HDMI_DFM_MAGNIFICATION_8;
/*
* 4. Determine Required Characters to carry Active Video per line.
* 3 is means active_bytes_per_line need 3 characters.
*/
info->activeTbPerLine = (info->activeBytesPerLine + 3 - 1) / 3;
/* 5. Determine Required Characters to carry H-Blank Video per line. */
info->hblankTbPerLine = (param->hblank * kcd / k420 + HDMI_DFM_MAGNIFICATION_8 - 1) / HDMI_DFM_MAGNIFICATION_8;
/* 6. 32 is FRL characters each packet, 7 is guard bands island(4 FRL char) + video(3 FRL char) */
if (((param->hblank * kcd) / k420) / HDMI_DFM_MAGNIFICATION_8 > 32 * (1 + info->audioPacketsLine) + 7) {
info->cFrlFree = ((param->hblank * kcd) / k420) / HDMI_DFM_MAGNIFICATION_8 -
32 * (1 + info->audioPacketsLine) - 7;
}
/* 7. add 1 character each for RC break caused by 4 */
info->cFrlRcMargin = 4;
/* 8. RC compression transmit control characters reduce 7/8th total characters. */
if (7 * info->cFrlFree / HDMI_DFM_MAGNIFICATION_8 > info->cFrlRcMargin) {
info->cFrlRcSavings = 7 * info->cFrlFree / HDMI_DFM_MAGNIFICATION_8 - info->cFrlRcMargin;
}
if (info->htotal == 0) {
HDF_LOGE("htotal is 0!");
return;
}
info->avgTbRate = info->maxPixelClk * (info->activeTbPerLine + info->hblankTbPerLine) / info->htotal;
info->activeTimeRef = (uint64_t)info->lineMinTime * param->hactive / info->htotal;
info->blankTimeRef = (uint64_t)info->lineMinTime * param->hblank / info->htotal;
/* 9. (3 / 2) is active_tb coefficient in protocol */
info->activeTimeMin = (uint64_t)info->activeTbPerLine * 3 * 100000000000000 /
(2 * param->laneNum * info->minFrlCharRate * (HDMI_DFM_RATE_MAGNIFICATION - info->overheadMax) /
HDMI_DFM_THOUSAND);
info->blankTimeMin = (uint64_t)info->hblankTbPerLine * 100000000000000 /
(param->laneNum * info->minFrlCharRate * (HDMI_DFM_RATE_MAGNIFICATION - info->overheadMax) /
HDMI_DFM_THOUSAND);
/* 10. Determine Borrow Info */
HdmiDfmCaculateVideoBorrowInfo(info);
/* 11. (3 / 2) is active_tb coefficient in protocol */
info->cFrlActualPayload =
(3 * info->activeTbPerLine + 2 - 1) / 2 + info->hblankTbPerLine - info->cFrlRcSavings;
if (info->minFrlCharsPerLine == 0) {
HDF_LOGE("min FRL Characters per line is 0!");
return;
}
info->utilization = (uint64_t)info->cFrlActualPayload * 100000 / (uint64_t)info->minFrlCharsPerLine;
info->margin = 100000 - (info->utilization + info->overheadMax);
}
static void HdmiDfmFillInfo(struct HdmiDfmInfo *info, struct HdmiDfmParam *param)
{
HdmiDfmBaseInfoInit(info, param);
HdmiDfmCaculateAudioInfo(info, param);
HdmiDfmCaculateVideoInfo(info, param);
/* Check Audio Cap. */
info->audioSupport = (info->hblankTbPerLine >= info->hblankAudioMin) ? true : false;
/* Check Video Cap. */
if (info->tbBorrow == HDMI_DFM_INVALID_VAL) {
info->videoSupport = false;
} else {
info->videoSupport = (info->tbBorrow <= HDMI_DFM_FRL_MAX_TB_BORROW) ? true : false;
}
info->uncompressSupport = (info->margin >= 0) ? true : false;
info->canbeTrans = (info->audioSupport && info->videoSupport && info->uncompressSupport) ? true : false;
info->isExtraMode = (info->canbeTrans && (info->tbBorrow > 0)) ? true : false;
}
bool HdmiDfmFormatSupport(struct HdmiDfmParam *param)
{
struct HdmiDfmInfo info = {0};
HdmiDfmFillInfo(&info, param);
if (info.audioSupport == true && info.videoSupport == true && info.uncompressSupport == true) {
return true;
}
return false;
}
+265
View File
@@ -0,0 +1,265 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "hdf_log.h"
#include "hdmi_dispatch.h"
#include "hdmi_core.h"
#include "hdmi_if.h"
#define HDF_LOG_TAG hdmi_dispatch_c
enum HdmiIoCmd {
HDMI_CMD_OPEN,
HDMI_CMD_CLOSE,
HDMI_CMD_START,
HDMI_CMD_STOP,
HDMI_CMD_AVMUTE_SET,
HDMI_CMD_DEEP_COLOR_SET,
HDMI_CMD_DEEP_COLOR_GET,
HDMI_CMD_VIDEO_ATTR_SET,
HDMI_CMD_AUDIO_ATTR_SET,
HDMI_CMD_HDR_ATTR_SET,
HDMI_CMD_READ_SINK_EDID,
HDMI_CMD_INFOFRAME_SET,
HDMI_CMD_INFOFRAME_GET,
HDMI_CMD_BUTT,
};
struct HdmiDispatchFunc {
int32_t cmd;
int32_t (*func)(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply);
};
static int32_t HdmiCmdOpen(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
{
(void)data;
(void)reply;
return HdmiCntlrOpen(cntlr);
}
static int32_t HdmiCmdClose(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
{
(void)data;
(void)reply;
HdmiCntlrClose(cntlr);
return HDF_SUCCESS;
}
static int32_t HdmiCmdStart(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
{
(void)data;
(void)reply;
return HdmiCntlrStart(cntlr);
}
static int32_t HdmiCmdStop(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
{
(void)data;
(void)reply;
return HdmiCntlrStop(cntlr);
}
static int32_t HdmiCmdAvmuteSet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
{
bool *enable = NULL;
size_t size;
(void)reply;
if (!HdfSbufReadBuffer(data, (const void **)&enable, &size)) {
HDF_LOGE("HdmiCmdAvmuteSet: sbuf read buffer failed");
return HDF_ERR_IO;
}
HdmiCntlrAvmuteSet(cntlr, *enable);
return HDF_SUCCESS;
}
static int32_t HdmiCmdDeepColorSet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
{
enum HdmiDeepColor *color = NULL;
size_t size;
(void)reply;
if (!HdfSbufReadBuffer(data, (const void **)&color, &size)) {
HDF_LOGE("HdmiCmdDeepColorSet: sbuf read buffer failed");
return HDF_ERR_IO;
}
return HdmiCntlrDeepColorSet(cntlr, *color);
}
static int32_t HdmiCmdDeepColorGet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
{
int32_t ret;
enum HdmiDeepColor color;
(void)data;
if (reply == NULL) {
return HDF_ERR_INVALID_PARAM;
}
ret = HdmiCntlrDeepColorGet(cntlr, &color);
if (ret != HDF_SUCCESS) {
return ret;
}
if (HdfSbufWriteBuffer(reply, &color, sizeof(color)) == false) {
HDF_LOGE("HdmiCmdDeepColorGet: write back color fail!");
return HDF_ERR_IO;
}
return HDF_SUCCESS;
}
static int32_t HdmiCmdVideoAttrSet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
{
struct HdmiVideoAttr *attr = NULL;
size_t size;
(void)reply;
if (!HdfSbufReadBuffer(data, (const void **)&attr, &size)) {
HDF_LOGE("HdmiCmdVideoAttrSet: sbuf read buffer failed");
return HDF_ERR_IO;
}
return HdmiCntlrSetVideoAttribute(cntlr, attr);
}
static int32_t HdmiCmdAudioAttrSet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
{
struct HdmiAudioAttr *attr = NULL;
size_t size;
(void)reply;
if (!HdfSbufReadBuffer(data, (const void **)&attr, &size)) {
HDF_LOGE("HdmiCmdAudioAttrSet: sbuf read buffer failed");
return HDF_ERR_IO;
}
return HdmiCntlrSetAudioAttribute(cntlr, attr);
}
static int32_t HdmiCmdHdrAttrSet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
{
struct HdmiHdrAttr *attr = NULL;
size_t size;
(void)reply;
if (!HdfSbufReadBuffer(data, (const void **)&attr, &size)) {
HDF_LOGE("HdmiCmdHdrAttrSet: sbuf read buffer failed");
return HDF_ERR_IO;
}
return HdmiCntlrSetHdrAttribute(cntlr, attr);
}
static int32_t HdmiCmdReadSinkEdid(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
{
int32_t ret;
uint8_t edid[HDMI_EDID_TOTAL_SIZE] = {0};
(void)data;
if (reply == NULL) {
return HDF_ERR_INVALID_PARAM;
}
ret = HdmiCntlrGetSinkEdid(cntlr, edid, HDMI_EDID_TOTAL_SIZE);
if (ret != HDF_SUCCESS) {
return ret;
}
if (HdfSbufWriteBuffer(reply, edid, HDMI_EDID_TOTAL_SIZE) == false) {
HDF_LOGE("HdmiCmdReadSinkEdid: write back edid fail!");
return HDF_ERR_IO;
}
return HDF_SUCCESS;
}
static int32_t HdmiCmdInfoframeSet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
{
enum HdmiPacketType type;
union HdmiInfoframeInfo *frame = NULL;
size_t size;
if (!HdfSbufReadUint16(data, (uint16_t *)&type)) {
HDF_LOGE("HdmiCmdInfoframeSet: sbuf read uint16 failed");
return HDF_ERR_IO;
}
if (!HdfSbufReadBuffer(data, (const void **)&frame, &size)) {
HDF_LOGE("HdmiCmdInfoframeSet: sbuf read buffer failed");
return HDF_ERR_IO;
}
return HdmiCntlrInfoframeSet(cntlr, type, frame);
}
static int32_t HdmiCmdInfoframeGet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
{
size_t size;
int32_t ret;
enum HdmiPacketType *type = NULL;
union HdmiInfoframeInfo frame = {0};
if (!HdfSbufReadBuffer(data, (const void **)&type, &size)) {
HDF_LOGE("HdmiCmdInfoframeGet: sbuf read buffer failed");
return HDF_ERR_IO;
}
ret = HdmiCntlrInfoframeGet(cntlr, *type, &frame);
if (ret != HDF_SUCCESS) {
return ret;
}
if (HdfSbufWriteBuffer(reply, &frame, sizeof(frame)) == false) {
HDF_LOGE("HdmiCmdInfoframeGet: write back frame fail!");
return HDF_ERR_IO;
}
return HDF_SUCCESS;
}
int32_t HdmiIoDispatch(struct HdfDeviceIoClient *client, int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
{
struct HdmiCntlr *cntlr = NULL;
uint32_t i, len;
struct HdmiDispatchFunc dispatchFunc[] = {
{ HDMI_CMD_OPEN, HdmiCmdOpen },
{ HDMI_CMD_CLOSE, HdmiCmdClose },
{ HDMI_CMD_START, HdmiCmdStart },
{ HDMI_CMD_STOP, HdmiCmdStop },
{ HDMI_CMD_AVMUTE_SET, HdmiCmdAvmuteSet },
{ HDMI_CMD_DEEP_COLOR_SET, HdmiCmdDeepColorSet },
{ HDMI_CMD_DEEP_COLOR_GET, HdmiCmdDeepColorGet },
{ HDMI_CMD_VIDEO_ATTR_SET, HdmiCmdVideoAttrSet },
{ HDMI_CMD_AUDIO_ATTR_SET, HdmiCmdAudioAttrSet },
{ HDMI_CMD_HDR_ATTR_SET, HdmiCmdHdrAttrSet },
{ HDMI_CMD_READ_SINK_EDID, HdmiCmdReadSinkEdid },
{ HDMI_CMD_INFOFRAME_SET, HdmiCmdInfoframeSet },
{ HDMI_CMD_INFOFRAME_GET, HdmiCmdInfoframeGet },
};
if (client == NULL || client->device == NULL) {
HDF_LOGE("HdmiIoDispatch: client or hdf dev obj is NULL");
return HDF_ERR_INVALID_OBJECT;
}
cntlr = (struct HdmiCntlr *)client->device->service;
if (cntlr == NULL) {
HDF_LOGE("HdmiIoDispatch: service is NULL");
return HDF_ERR_INVALID_OBJECT;
}
len = sizeof(dispatchFunc) / sizeof(dispatchFunc[0]);
for (i = 0; i < len; i++) {
if (dispatchFunc[i].cmd == cmd) {
return dispatchFunc[i].func(cntlr, data, reply);
}
}
HDF_LOGE("HdmiIoDispatch: cmd %d is not support", cmd);
return HDF_ERR_NOT_SUPPORT;
}
File diff suppressed because it is too large Load Diff
+266
View File
@@ -0,0 +1,266 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "hdf_log.h"
#include "hdmi_core.h"
#include "osal_mem.h"
#define HDF_LOG_TAG hdmi_event_c
static int32_t HdmiEventPostMsg(struct HdmiCntlr *cntlr, struct HdmiEventMsg *event)
{
int32_t ret;
if (cntlr == NULL) {
return HDF_ERR_INVALID_OBJECT;
}
if (event == NULL) {
return HDF_ERR_INVALID_PARAM;
}
PlatformQueueAddMsg(cntlr->msgQueue, &event->msg);
ret = PlatformMsgWait(&event->msg);
if (event->msg.block == true) {
(void)OsalSemDestroy(&event->msg.sem);
OsalMemFree(event);
}
if (ret != HDF_SUCCESS) {
HDF_LOGE("HdmiEventPostMsg: wait hdmi event msg fail!");
return ret;
}
return HDF_SUCCESS;
}
bool HdmiHpdStatusGet(struct HdmiCntlr *cntlr)
{
bool ret;
if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->hotPlugStateGet == NULL) {
return false;
}
HdmiCntlrLock(cntlr);
ret = cntlr->ops->hotPlugStateGet(cntlr);
HdmiCntlrUnlock(cntlr);
return ret;
}
bool HdmiHpdStatusDelayGet(struct HdmiCntlr *cntlr)
{
uint32_t i;
/*
* An HDMI Sink shall indicate any change to the contents of the EDID by driving a low voltage level pulse
* on the Hot Plug Detect pin. This pluse shall be at least 100 msec.
*/
for (i = 0; i < HDMI_READ_HPD_STATUS_DELAY; i++) {
if (HdmiHpdStatusGet(cntlr) == true) {
return true;
}
OsalMSleep(1);
}
return false;
}
int32_t HdmiAddEventMsgToQueue(struct HdmiCntlr *cntlr, int32_t code, bool block, void *data)
{
struct HdmiEventMsg *event = NULL;
if (cntlr == NULL) {
return HDF_ERR_INVALID_OBJECT;
}
event = (struct HdmiEventMsg *)OsalMemCalloc(sizeof(struct HdmiEventMsg));
if (event == NULL) {
HDF_LOGE("HdmiAddEventMsgToQueue: OsalMemCalloc fail!n");
return HDF_ERR_MALLOC_FAIL;
}
event->msg.code = code;
event->msg.data = (void *)cntlr;
event->msg.block = block;
event->priv = data;
return HdmiEventPostMsg(cntlr, event);
}
static int32_t HdmiEventHotPlugHandleComm(struct HdmiCntlr *cntlr)
{
int32_t ret;
cntlr->event.plugged = true;
if (cntlr->hdmi == NULL) {
ret = HdmiCntlrAllocDev(cntlr);
if (ret != HDF_SUCCESS) {
goto __END;
}
HDF_LOGE("HdmiEventHotPlugHandleComm HdmiCntlrAllocDev success.");
}
/* Update EDID. */
if (memset_s(cntlr->hdmi, sizeof(struct HdmiDevice), 0, sizeof(struct HdmiDevice)) != EOK) {
HDF_LOGE("memcpy_s fail.");
ret = HDF_ERR_IO;
goto __END;
}
ret = HdmiEdidRawDataRead(&(cntlr->hdmi->edid), &(cntlr->ddc));
if (ret != HDF_SUCCESS) {
goto __END;
}
ret = HdmiEdidPhase(&(cntlr->hdmi->edid));
if (ret != HDF_SUCCESS) {
goto __END;
}
__END:
if (ret != HDF_SUCCESS) {
cntlr->event.plugged = false;
cntlr->event.hpdDetected = false;
return ret;
}
cntlr->event.hpdDetected = true;
return HDF_SUCCESS;
}
static int32_t HdmiEventHotPlugHandle(struct HdmiCntlr *cntlr)
{
if (HdmiHpdStatusDelayGet(cntlr) == false) {
HDF_LOGD("not detect HPD.");
return HDF_ERR_IO;
}
if (cntlr->event.plugged == true) {
HDF_LOGD("hdp state not change");
return HDF_SUCCESS;
}
return HdmiEventHotPlugHandleComm(cntlr);
}
static int32_t HdmiEventHotUnplugHandle(struct HdmiCntlr *cntlr)
{
if (cntlr->event.plugged == false) {
HDF_LOGD("plug state not change");
return HDF_SUCCESS;
}
HdmiCntlrClose(cntlr);
HdmiCntlrFreeDev(cntlr);
cntlr->event.plugged = false;
cntlr->event.hpdDetected = false;
return HDF_SUCCESS;
}
static int32_t HdmiEventDetectSinkHandle(struct HdmiCntlr *cntlr)
{
if (HdmiHpdStatusDelayGet(cntlr) == false) {
HDF_LOGD("not detect HPD.");
return HDF_SUCCESS;
}
return HdmiEventHotPlugHandleComm(cntlr);
}
static int32_t HdmiEventCecMsgHandle(struct HdmiCntlr *cntlr, struct HdmiCecMsg *msg)
{
if (msg == NULL) {
return HDF_ERR_INVALID_OBJECT;
}
return HdmiCecReceivedMsg(cntlr->cec, msg);
}
static int32_t HdmiEventHdrZeroDrmIfTimeout(struct HdmiCntlr *cntlr)
{
return HdmiHdrDrmInfoframeStop(cntlr->hdr);
}
static int32_t HdmiEventSwitchToHdrModeTimeout(struct HdmiCntlr *cntlr)
{
return HdmiHdrModeChangeTimeout(cntlr->hdr);
}
int32_t HdmiEventMsgHandleDefault(struct PlatformQueue *queue, struct PlatformMsg *msg)
{
int32_t ret;
struct HdmiCntlr *cntlr = NULL;
struct HdmiEventMsg *event = NULL;
if (queue == NULL || msg == NULL) {
HDF_LOGE("HdmiEventMsgHandleDefault: msg or queue is null!");
return HDF_ERR_INVALID_OBJECT;
}
cntlr = (struct HdmiCntlr *)queue->data;
if (cntlr == NULL) {
HDF_LOGE("HdmiEventMsgHandleDefault: cntlr is null!");
return HDF_ERR_INVALID_OBJECT;
}
event = (struct HdmiEventMsg *)msg;
switch (msg->code) {
case HDMI_EVENT_HOTPLUG :
ret = HdmiEventHotPlugHandle(cntlr);
break;
case HDMI_EVENT_HOTUNPLUG :
ret = HdmiEventHotUnplugHandle(cntlr);
break;
case HDMI_EVENT_DETECT_SINK :
ret = HdmiEventDetectSinkHandle(cntlr);
break;
case HDMI_EVENT_CEC_MSG:
ret = HdmiEventCecMsgHandle(cntlr, event->priv);
break;
case HDMI_EVENT_ZERO_DRMIF_TIMEOUT :
ret = HdmiEventHdrZeroDrmIfTimeout(cntlr);
break;
case HDMI_EVENT_SWITCH_TO_HDRMODE_TIMEOUT :
ret = HdmiEventSwitchToHdrModeTimeout(cntlr);
break;
default:
ret = HDF_ERR_NOT_SUPPORT;
break;
}
if (event->msg.block == false) {
OsalMemFree(event);
}
return ret;
}
int32_t HdmiEventHandle(struct HdmiCntlr *cntlr, enum HdmiEventType event, void *data)
{
int32_t ret = HDF_SUCCESS;
if (cntlr == NULL) {
HDF_LOGE("HdmiEventHandleIrq: cntlr is null!");
return HDF_ERR_INVALID_OBJECT;
}
switch (event) {
case HDMI_EVENT_HOTPLUG :
ret = HdmiAddEventMsgToQueue(cntlr, HDMI_EVENT_HOTPLUG, false, data);
break;
case HDMI_EVENT_HOTUNPLUG :
ret = HdmiAddEventMsgToQueue(cntlr, HDMI_EVENT_HOTUNPLUG, false, data);
break;
case HDMI_EVENT_DETECT_SINK :
ret = HdmiAddEventMsgToQueue(cntlr, HDMI_EVENT_DETECT_SINK, false, data);
break;
case HDMI_EVENT_CEC_MSG :
ret = HdmiAddEventMsgToQueue(cntlr, HDMI_EVENT_CEC_MSG, false, data);
break;
case HDMI_EVENT_HDCP_MSG :
ret = HdmiAddEventMsgToQueue(cntlr, HDMI_EVENT_HDCP_MSG, false, data);
break;
case HDMI_EVENT_ZERO_DRMIF_TIMEOUT :
ret = HdmiAddEventMsgToQueue(cntlr, HDMI_EVENT_ZERO_DRMIF_TIMEOUT, false, data);
break;
case HDMI_EVENT_SWITCH_TO_HDRMODE_TIMEOUT :
ret = HdmiAddEventMsgToQueue(cntlr, HDMI_EVENT_SWITCH_TO_HDRMODE_TIMEOUT, false, data);
break;
default :
HDF_LOGE("event %d is not support", event);
break;
}
return ret;
}
+869
View File
@@ -0,0 +1,869 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "hdf_log.h"
#include "hdmi_core.h"
#include "hdmi_common.h"
#include "hdmi_dfm.h"
#include "hdmi_ncts.h"
#define HDF_LOG_TAG hdmi_frl_c
static uint8_t HdmiFrlGetSinkVersion(struct HdmiScdc *scdc)
{
uint8_t version = 0;
if (HdmiScdcOptMsgHandle(scdc, HDMI_SCDC_OPT_GET_SINK_VER, &version, sizeof(version)) != HDF_SUCCESS) {
HDF_LOGD("frl get sink version fail");
return 0;
}
return version;
}
static bool HdmiFrlGetFltUpdate(struct HdmiScdc *scdc)
{
bool fltUpdate = false;
uint8_t flag = 0;
if (HdmiScdcOptMsgHandle(scdc, HDMI_SCDC_OPT_GET_FLT_UPDATE, &flag, sizeof(flag)) != HDF_SUCCESS) {
HDF_LOGD("frl get flt update fail");
return fltUpdate;
}
fltUpdate = (flag & HDMI_SCDC_FLT_UPDATE_MARK) ? true : false;
return fltUpdate;
}
static bool HdmiFrlGetFrlStart(struct HdmiScdc *scdc)
{
bool frlStart = false;
uint8_t flag = 0;
if (HdmiScdcOptMsgHandle(scdc, HDMI_SCDC_OPT_GET_FLT_UPDATE, &flag, sizeof(flag)) != HDF_SUCCESS) {
HDF_LOGD("frl get frl start fail");
return frlStart;
}
frlStart = (flag & HDMI_SCDC_FRL_START_MARK) ? true : false;
return frlStart;
}
static bool HdmiFrlGetFltReady(struct HdmiScdc *scdc)
{
bool fltReady = false;
uint8_t flag = 0;
if (HdmiScdcOptMsgHandle(scdc, HDMI_SCDC_OPT_GET_FLT_READY, &flag, sizeof(flag)) != HDF_SUCCESS) {
HDF_LOGD("frl get flt ready fail");
return fltReady;
}
fltReady = (flag & HDMI_SCDC_FLT_READY_MARK) ? true : false;
return fltReady;
}
static uint8_t HdmiFrlGetTestConfig1(struct HdmiScdc *scdc)
{
uint8_t cfg = 0;
if (HdmiScdcOptMsgHandle(scdc, HDMI_SCDC_OPT_GET_TEST_CONFIG_1, &cfg, sizeof(cfg)) != HDF_SUCCESS) {
HDF_LOGD("frl get test cfg1 fail");
return 0;
}
return cfg;
}
static void HdmiFrlSetFltUpdate(struct HdmiScdc *scdc, bool fltUpdate)
{
uint8_t flag = 0;
if (HdmiScdcOptMsgHandle(scdc, HDMI_SCDC_OPT_GET_FLT_UPDATE, &flag, sizeof(flag)) != HDF_SUCCESS) {
HDF_LOGD("frl get flt update fail");
return;
}
if (fltUpdate == true) {
flag |= HDMI_SCDC_FLT_UPDATE_MARK;
} else {
flag &= (~HDMI_SCDC_FLT_UPDATE_MARK);
}
if (HdmiScdcOptMsgHandle(scdc, HDMI_SCDC_OPT_SET_FLT_UPDATE, &flag, sizeof(flag)) != HDF_SUCCESS) {
HDF_LOGD("frl set flt update fail");
}
}
static void HdmiFrlSetFrlStart(struct HdmiScdc *scdc, bool frlStart)
{
uint8_t flag = 0;
if (HdmiScdcOptMsgHandle(scdc, HDMI_SCDC_OPT_GET_FLT_UPDATE, &flag, sizeof(flag)) != HDF_SUCCESS) {
HDF_LOGD("frl get frl start fail");
return;
}
if (frlStart == true) {
flag |= HDMI_SCDC_FRL_START_MARK;
} else {
flag &= (~HDMI_SCDC_FRL_START_MARK);
}
if (HdmiScdcOptMsgHandle(scdc, HDMI_SCDC_OPT_GET_FLT_UPDATE, &flag, sizeof(flag)) != HDF_SUCCESS) {
HDF_LOGD("frl set frl start fail");
}
}
static void HdmiFrlSetConfig1(struct HdmiScdc *scdc, uint8_t *data)
{
if (HdmiScdcOptMsgHandle(scdc, HDMI_SCDC_OPT_SET_CONFIG1, data, sizeof(*data)) != HDF_SUCCESS) {
HDF_LOGD("frl set cfg1 fail");
}
}
static void HdmiFrlSetTrainRate(struct HdmiFrl *frl)
{
union HdmiScdcsConfig1 cfg = {0};
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
if (cntlr == NULL) {
HDF_LOGE("frl set train rate fail");
return;
}
if (frl->info.mode == HDMI_FRL_MODE_FRL) {
cfg.bits.frlRate = frl->info.curFrlRate;
cfg.bits.ffeLevels = HDMI_FRL_TXFFE_MODE_0;
}
HdmiFrlSetConfig1(cntlr->scdc, &(cfg.data));
}
static bool HdmiFrlCheckFrlCapability(struct HdmiFrl *frl)
{
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
uint8_t sinkScdcVerion;
uint8_t sinkMaxFrlRate;
sinkScdcVerion = HdmiFrlGetSinkVersion(cntlr->scdc);
if (HdmiEdidSupportFrl(cntlr->hdmi) != true ||
cntlr->cap.baseCap.bits.hdmi21 == 0 ||
cntlr->cap.baseCap.bits.frl == 0 ||
sinkScdcVerion == 0) {
frl->info.maxFrlRate = 0;
return HDF_ERR_NOT_SUPPORT;
}
sinkMaxFrlRate = HdmiEdidGetMaxFrlRate(cntlr->hdmi);
frl->info.maxFrlRate = (sinkMaxFrlRate > cntlr->cap.maxFrlRate) ? cntlr->cap.maxFrlRate : sinkMaxFrlRate;
return HDF_SUCCESS;
}
static bool HdmiFrlCheckFrlStrategy(enum HdmiFrlStrategyMode strategy, uint32_t pixelClock,
uint32_t tmdsClock, enum HdmiVideoFormatType formatType)
{
bool support = true;
switch (strategy) {
case HDMI_FRL_STRATEGY_MODE_1 :
if (pixelClock <= HDMI_HDMI20_MAX_TMDS_RATE && tmdsClock <= HDMI_HDMI20_MAX_TMDS_RATE) {
support = false;
}
break;
case HDMI_FRL_STRATEGY_MODE_2 :
if (tmdsClock <= HDMI_HDMI14_MAX_TMDS_RATE) {
support = false;
}
break;
case HDMI_FRL_STRATEGY_MODE_3 :
if (formatType == HDMI_VIDEO_FORMA_INTERLACE) {
support = false;
}
break;
default :
HDF_LOGE("strategy %d is not support", strategy);
break;
}
return support;
}
static void HdmiFrlFillRateInfo(uint32_t *frlBitRate, uint32_t *frlLaneNum, uint32_t frlRate)
{
*frlLaneNum = HDMI_FRL_4_LANES;
if (frlRate <= HDMI_FRL_WORK_MODE_3L6G) {
*frlLaneNum = HDMI_FRL_3_LANES;
}
switch (frlRate) {
case HDMI_FRL_WORK_MODE_3L3G :
*frlBitRate = HDMI_FRL_BIT_RATE_3;
break;
case HDMI_FRL_WORK_MODE_3L6G :
case HDMI_FRL_WORK_MODE_4L6G :
*frlBitRate = HDMI_FRL_BIT_RATE_6;
break;
case HDMI_FRL_WORK_MODE_4L8G :
*frlBitRate = HDMI_FRL_BIT_RATE_8;
break;
case HDMI_FRL_WORK_MODE_4L10G :
*frlBitRate = HDMI_FRL_BIT_RATE_10;
break;
case HDMI_FRL_WORK_MODE_4L12G :
*frlBitRate = HDMI_FRL_BIT_RATE_12;
break;
default :
break;
}
}
static bool HdnmiFrlCheckFrlMode(struct HdmiFrl *frl)
{
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
struct HdmiVideoDefInfo *videoInfo = NULL;
struct HdmiDfmParam param = {0};
bool enable3d;
uint32_t i;
enable3d = (cntlr->attr.videoAttr._3dStruct >= HDMI_VS_VIDEO_3D_BUTT) ? false : true;
videoInfo = HdmiCommonGetVideoDefInfo(cntlr->attr.videoAttr.timing, cntlr->attr.videoAttr.aspect, enable3d);
if (videoInfo == NULL) {
HDF_LOGD("have no this video param, use tmds to transmit.");
return false;
}
HDF_LOGD("use frl to transmit, vic is %d.", videoInfo->vic);
frl->info.tmdsClock = cntlr->attr.videoAttr.tmdsClock;
if (HdmiFrlCheckFrlStrategy(frl->info.strategy, cntlr->attr.videoAttr.pixelClock,
frl->info.tmdsClock, videoInfo->formatType) == false) {
return false;
}
if (frl->info.maxFrlRate > HDMI_FRL_WORK_MODE_4L12G) {
HDF_LOGD("max frl rate is wrong(%u)", frl->info.maxFrlRate);
frl->info.maxFrlRate = HDMI_FRL_WORK_MODE_4L12G;
return true;
}
/* Check whether a particular video format can be transmitted in a particular FRL configuration. */
HdmiDfmFillParam(&param, videoInfo, &(cntlr->attr.audioAttr), cntlr->attr.commAttr.colorSpace,
cntlr->attr.commAttr.deepColor);
for (i = frl->info.maxFrlRate; i > 0; i--) {
HdmiFrlFillRateInfo(&(param.bitRate), &(param.laneNum), i);
if (HdmiDfmFormatSupport(&param) == true) {
frl->info.minFrlRate = i;
HDF_LOGD("min_rate: %d", i);
} else {
break;
}
}
if (i == frl->info.maxFrlRate) {
return false;
}
return true;
}
static bool HdmiFrlIsCtsMode(struct HdmiFrl *frl)
{
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
union HdmiScdcsTestConfig1 cfg = {0};
cfg.data = HdmiFrlGetTestConfig1(cntlr->scdc);
if ((cfg.bits.frlMax > 0 && cfg.bits.dscFrlMax == 0) ||
(cfg.bits.frlMax == 0 && cfg.bits.dscFrlMax > 0)) {
return true;
}
return false;
}
static int32_t HdmiFrlGetCurRate(struct HdmiFrl *frl)
{
uint8_t curFrlrate = frl->info.curFrlRate;
if (frl->info.ctsMode == true) {
frl->info.preFrlRate = curFrlrate;
curFrlrate = frl->info.maxFrlRate;
} else {
if (frl->info.preFrlRate != 0) {
curFrlrate = frl->info.preFrlRate;
frl->info.preFrlRate = 0;
} else {
if (frl->info.rateSelect == HDMI_FRL_RATE_BIG) {
curFrlrate--;
} else {
curFrlrate++;
}
}
}
if ((curFrlrate > frl->info.maxFrlRate) ||
(curFrlrate < frl->info.minFrlRate)) {
return HDF_FAILURE;
}
frl->info.curFrlRate = curFrlrate;
return HDF_SUCCESS;
}
static void HdmiFrlAudioNctsSet(struct HdmiFrl *frl)
{
struct HdmiFrlAudioNctsConfig cfg = {0};
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->audioNctsSet == NULL) {
HDF_LOGD("not support set frl audio ncts.");
return;
}
cfg.mode = frl->info.mode;
cfg.sampleRate = cntlr->attr.audioAttr.sampleRate;
if (cfg.mode == HDMI_FRL_MODE_FRL) {
cfg.frlRate = frl->info.curFrlRate;
} else {
cfg.pixelClk = cntlr->attr.videoAttr.pixelClock;
cfg.n = HdmiGetN(cfg.sampleRate, cfg.pixelClk);
cfg.cts = HdmiGetCts(cfg.sampleRate, cfg.pixelClk);
}
HdmiCntlrLock(cntlr);
cntlr->ops->audioNctsSet(cntlr, &cfg);
HdmiCntlrUnlock(cntlr);
}
static void HdmiFrlTxffeSet(struct HdmiFrl *frl)
{
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
struct HdmiPhyCfg cfg = {0};
if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->phyOutputSet == NULL) {
HDF_LOGD("not support phy output set.");
return;
}
cfg.modeCfg = HDMI_PHY_MODE_TXFFE;
cfg.rate = (enum HdmiFrlWorkMode)frl->info.curFrlRate;
HdmiCntlrLock(cntlr);
cntlr->ops->phyOutputSet(cntlr, &cfg);
HdmiCntlrUnlock(cntlr);
}
static void HdmiFrlphyConfigSet(struct HdmiFrl *frl)
{
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
struct HdmiPhyCfg cfg = {0};
if (cntlr == NULL || cntlr->ops == NULL) {
return;
}
cfg.tmdsClk = cntlr->attr.videoAttr.tmdsClock;
cfg.pixelClk = cntlr->attr.videoAttr.pixelClock;
cfg.deepColor = cntlr->attr.videoAttr.deepColor;
cfg.colorSpace = cntlr->attr.commAttr.colorSpace;
if (frl->info.mode == HDMI_FRL_MODE_FRL) {
cfg.modeCfg = HDMI_PHY_MODE_FRL;
cfg.rate = (enum HdmiFrlWorkMode)frl->info.curFrlRate;
}
if (cntlr->ops->phyOutputEnable != NULL) {
HdmiCntlrLock(cntlr);
cntlr->ops->phyOutputEnable(cntlr, false);
HdmiCntlrUnlock(cntlr);
}
if (cntlr->ops->phyOutputSet != NULL) {
HdmiCntlrLock(cntlr);
cntlr->ops->phyOutputSet(cntlr, &cfg);
HdmiCntlrUnlock(cntlr);
}
if (cntlr->ops->phyOutputEnable != NULL) {
HdmiCntlrLock(cntlr);
cntlr->ops->phyOutputEnable(cntlr, true);
HdmiCntlrUnlock(cntlr);
}
}
static void HdmiFrlStateMachineChangeState(struct HdmiFrl *frl, enum HdmiFrlTrainStep state)
{
/* change state machine's state */
frl->info.machineInfo.trainingState = state;
/* restart timer */
frl->info.machineInfo.startTime = OsalGetSysTimeMs();
}
static void HdmiFrlTrainingReadyCheck(struct HdmiFrl *frl)
{
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
if (HdmiFrlGetFltReady(cntlr->scdc) == true) {
HDF_LOGD("step, ready chack pass, start training.");
HdmiFrlphyConfigSet(frl);
HdmiFrlSetTrainRate(frl);
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_TRAIN_START);
}
}
static void HdmiFrlConfigAndStartTraining(struct HdmiFrl *frl)
{
struct HdmiFrlTrainConfig cfg = {0};
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
union HdmiScdcsTestConfig1 testCfg = {0};
if (cntlr == NULL || cntlr->ops == NULL) {
return;
}
cfg.frlRate = frl->info.curFrlRate;
cfg.txffe = HDMI_FRL_TXFFE_MODE_0;
testCfg.data = HdmiFrlGetTestConfig1(cntlr->scdc);
if (testCfg.bits.fltNoTimeout > 0) {
cfg.frlNoTimeout = true;
}
cfg.trainTimeout = frl->info.machineInfo.trainTimeout;
if (cntlr->ops->frlTrainingConfigSet != NULL) {
HdmiCntlrLock(cntlr);
cntlr->ops->frlTrainingConfigSet(cntlr, &cfg);
HdmiCntlrUnlock(cntlr);
}
if (cntlr->ops->frlEnable != NULL) {
HdmiCntlrLock(cntlr);
cntlr->ops->frlEnable(cntlr, false);
HdmiCntlrUnlock(cntlr);
}
if (cntlr->ops->frlTrainingStart != NULL) {
HdmiCntlrLock(cntlr);
cntlr->ops->frlTrainingStart(cntlr);
HdmiCntlrUnlock(cntlr);
}
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_RESULT_CHECK);
return;
}
static void HdmiFrlTrainingResultCheck(struct HdmiFrl *frl)
{
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
struct HdmiFrlTrainRslt rslt = {0};
if (cntlr != NULL && cntlr->ops != NULL && cntlr->ops->frlGetTriningRslt != NULL) {
cntlr->ops->frlGetTriningRslt(cntlr, &rslt);
}
if (rslt.status == HDMI_FRL_TRAIN_STATUS_SUCC) {
frl->info.trainingFailCnt = 0;
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_RESULT_HANDLE);
} else if (rslt.failReason == HDMI_FRL_TRAIN_FAIL_FFE_CHANGE) {
frl->info.trainingFailCnt = 0;
HdmiFrlTxffeSet(frl);
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_TRAIN_START);
} else if (rslt.failReason == HDMI_FRL_TRAIN_FAIL_RATE_CHANGE) {
frl->info.trainingFailCnt = 0;
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_RATE_CHANGE);
} else {
(frl->info.trainingFailCnt)++;
}
}
static void HdmiFrlTrainingException(struct HdmiFrl *frl)
{
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
struct HdmiPhyCfg cfg = {0};
if (cntlr != NULL || cntlr->ops != NULL) {
return;
}
if (cntlr->ops->phyOutputEnable != NULL) {
cntlr->ops->phyOutputEnable(cntlr, false);
}
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_TRAIN_STOP);
frl->info.start = false;
/* TMDS config. */
cfg.pixelClk = cntlr->attr.videoAttr.pixelClock;
cfg.tmdsClk = cntlr->attr.videoAttr.tmdsClock;
cfg.deepColor = cntlr->attr.videoAttr.deepColor;
cfg.modeCfg = HDMI_PHY_MODE_TMDS;
cfg.colorSpace = cntlr->attr.commAttr.colorSpace;
HDF_LOGD("FRL change to TMDS.");
if (cfg.tmdsClk > HDMI_HDMI20_MAX_TMDS_RATE) {
HDF_LOGE("TMDS clk > 600M. can't work TMDS mode.");
return;
}
frl->info.mode = HDMI_FRL_MODE_TMDS;
HdmiFrlSetTrainRate(frl);
HdmiFrlAudioNctsSet(frl);
if (cntlr->ops->phyOutputSet != NULL) {
cntlr->ops->phyOutputSet(cntlr, &cfg);
}
if (cntlr->ops->phyOutputEnable != NULL) {
cntlr->ops->phyOutputEnable(cntlr, true);
}
}
static void HdmiFrlTrainingRateChange(struct HdmiFrl *frl)
{
frl->info.ctsMode = HdmiFrlIsCtsMode(frl);
if (HdmiFrlGetCurRate(frl) != HDF_SUCCESS) {
HDF_LOGE("FRL rate %u get failed!\n", frl->info.curFrlRate);
HdmiFrlTrainingException(frl);
return;
}
/* FRL rate change */
HdmiFrlphyConfigSet(frl);
HdmiFrlSetTrainRate(frl);
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_TRAIN_START);
}
static void HdmiFrlTrainingPassedCheck(struct HdmiFrl *frl)
{
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
if (cntlr != NULL || cntlr->ops != NULL) {
return;
}
if (frl->info.start == false ||
HdmiFrlGetFrlStart(cntlr->scdc) == false) {
return;
}
HDF_LOGD("FRL training passed.");
frl->info.work = true;
/* n/cts config */
HdmiFrlAudioNctsSet(frl);
OsalMSleep(1);
if (cntlr->ops->phyOutputEnable != NULL) {
HdmiCntlrLock(cntlr);
cntlr->ops->phyOutputEnable(cntlr, frl->info.work);
HdmiCntlrUnlock(cntlr);
}
OsalMSleep(1);
HdmiFrlSetFrlStart(cntlr->scdc, true);
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_RETRAIN_CHECK);
}
static void HdmiFrlRetrainingCheck(struct HdmiFrl *frl)
{
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
if (cntlr != NULL || cntlr->ops != NULL) {
return;
}
if (HdmiFrlGetFltUpdate(cntlr->scdc) == false) {
return;
}
HDF_LOGD("FRL retraining flt_update get OK");
HdmiFrlSetFltUpdate(cntlr->scdc, true);
frl->info.work = false;
if (cntlr->ops->phyOutputEnable != NULL) {
HdmiCntlrLock(cntlr);
cntlr->ops->phyOutputEnable(cntlr, frl->info.work);
HdmiCntlrUnlock(cntlr);
}
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_TRAIN_START);
}
static void HdmiFrlTrainingStop(struct HdmiFrl *frl)
{
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
if (cntlr != NULL || cntlr->ops != NULL) {
return;
}
frl->info.work = false;
if (cntlr->ops->phyOutputEnable != NULL) {
HdmiCntlrLock(cntlr);
cntlr->ops->phyOutputEnable(cntlr, frl->info.work);
HdmiCntlrUnlock(cntlr);
}
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_BUTT);
}
void HdmiFrlTrainingStateMachineHandle(struct HdmiFrl *frl)
{
if (frl == NULL) {
HDF_LOGE("FRL trining, not support FRL.");
return;
}
switch (frl->info.machineInfo.trainingState) {
case HDMI_FRL_TRAIN_STEP_READR_CHECK :
HdmiFrlTrainingReadyCheck(frl);
break;
case HDMI_FRL_TRAIN_STEP_TRAIN_START :
HdmiFrlConfigAndStartTraining(frl);
break;
case HDMI_FRL_TRAIN_STEP_RESULT_CHECK :
HdmiFrlTrainingResultCheck(frl);
break;
case HDMI_FRL_TRAIN_STEP_RATE_CHANGE :
HdmiFrlTrainingRateChange(frl);
break;
case HDMI_FRL_TRAIN_STEP_RESULT_HANDLE :
HdmiFrlTrainingPassedCheck(frl);
break;
case HDMI_FRL_TRAIN_STEP_RETRAIN_CHECK :
HdmiFrlRetrainingCheck(frl);
break;
case HDMI_FRL_TRAIN_STEP_TRAIN_STOP :
HdmiFrlTrainingStop(frl);
break;
default :
break;
}
}
static void HdmiFrlTrainingReadyCheckTimeout(struct HdmiFrl *frl)
{
uint64_t curTime = OsalGetSysTimeMs();
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
if ((curTime - frl->info.machineInfo.startTime) > frl->info.machineInfo.waitReadyTime) {
if (HdmiFrlGetFltReady(cntlr->scdc) == true) {
HDF_LOGD("step, ready chack pass, start training.");
frl->info.machineInfo.timeoutCnt = 0;
HdmiFrlphyConfigSet(frl);
HdmiFrlSetTrainRate(frl);
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_TRAIN_START);
} else {
(frl->info.machineInfo.timeoutCnt)++;
/* */
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_READR_CHECK);
}
} else {
/* wait for a maximum of 10 times, (wait_ready_ms * 10) ms */
if (frl->info.machineInfo.timeoutCnt < 10) {
return;
}
HDF_LOGD("FRL training READY_CHECK exception.");
frl->info.machineInfo.timeoutCnt = 0;
HdmiFrlTrainingException(frl);
}
}
static void HdmiFrlTrainingResultCheckTimeout(struct HdmiFrl *frl)
{
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
struct HdmiFrlTrainRslt rslt = {0};
if (cntlr != NULL && cntlr->ops != NULL && cntlr->ops->frlGetTriningRslt != NULL) {
cntlr->ops->frlGetTriningRslt(cntlr, &rslt);
}
if (rslt.status == HDMI_FRL_TRAIN_STATUS_SUCC) {
frl->info.trainingFailCnt = 0;
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_RESULT_HANDLE);
} else if (rslt.failReason == HDMI_FRL_TRAIN_FAIL_FFE_CHANGE) {
frl->info.trainingFailCnt = 0;
HdmiFrlTxffeSet(frl);
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_TRAIN_START);
} else if (rslt.failReason == HDMI_FRL_TRAIN_FAIL_RATE_CHANGE) {
frl->info.trainingFailCnt = 0;
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_RATE_CHANGE);
} else {
(frl->info.trainingFailCnt)++;
if (frl->info.trainingFailCnt > frl->info.trainingMaxFailTimes) {
frl->info.trainingFailCnt = 0;
HdmiFrlTrainingException(frl);
} else {
/* not reach max fail times, re-training. */
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_TRAIN_START);
}
}
}
static void HdmiFrlTrainingResultHandleTimeout(struct HdmiFrl *frl)
{
uint64_t curTime;
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
if (cntlr != NULL || cntlr->ops != NULL) {
return;
}
do {
if (HdmiFrlGetFrlStart(cntlr->scdc) == true) {
if (frl->info.start == true) {
frl->info.work = true;
/* n/cts config */
HdmiFrlAudioNctsSet(frl);
if (cntlr->ops->phyOutputEnable != NULL) {
cntlr->ops->phyOutputEnable(cntlr, frl->info.work);
}
HdmiFrlSetFrlStart(cntlr->scdc, true);
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_RETRAIN_CHECK);
break;
}
} else if (HdmiFrlGetFltUpdate(cntlr->scdc) == true) {
HdmiFrlSetFltUpdate(cntlr->scdc, true);
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_TRAIN_START);
break;
}
curTime = OsalGetSysTimeMs();
if ((curTime - frl->info.machineInfo.startTime) > frl->info.machineInfo.waitHandleTime) {
(frl->info.machineInfo.timeoutCnt)++;
break;
}
/* check the sink's status every 2ms required by protocol */
OsalUDelay(2000);
} while (true);
if (frl->info.machineInfo.timeoutCnt >= 3) {
HDF_LOGE("FRL training timeout.");
frl->info.machineInfo.timeoutCnt = 0;
HdmiFrlTrainingException(frl);
}
}
static void HdmiFrlRetrainingCheckTimeout(struct HdmiFrl *frl)
{
uint64_t curTime = OsalGetSysTimeMs();
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
if (cntlr != NULL || cntlr->ops != NULL) {
return;
}
if ((curTime - frl->info.machineInfo.startTime) <= frl->info.machineInfo.waitRetrainTime) {
return;
}
if (HdmiFrlGetFltUpdate(cntlr->scdc) != true) {
return;
}
HdmiFrlSetFltUpdate(cntlr->scdc, true);
frl->info.work = true;
if (cntlr->ops->phyOutputEnable != NULL) {
cntlr->ops->phyOutputEnable(cntlr, frl->info.work);
}
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_TRAIN_START);
}
void HdmiFrlTrainingStateMachineTimeoutHandle(struct HdmiFrl *frl)
{
if (frl == NULL || frl->priv == NULL) {
HDF_LOGE("FRL trining, not support FRL.");
return;
}
switch (frl->info.machineInfo.trainingState) {
case HDMI_FRL_TRAIN_STEP_READR_CHECK :
HdmiFrlTrainingReadyCheckTimeout(frl);
break;
case HDMI_FRL_TRAIN_STEP_TRAIN_START :
HdmiFrlConfigAndStartTraining(frl);
break;
case HDMI_FRL_TRAIN_STEP_RESULT_CHECK :
HdmiFrlTrainingResultCheckTimeout(frl);
break;
case HDMI_FRL_TRAIN_STEP_RATE_CHANGE :
HdmiFrlTrainingRateChange(frl);
break;
case HDMI_FRL_TRAIN_STEP_RESULT_HANDLE :
HdmiFrlTrainingResultHandleTimeout(frl);
break;
case HDMI_FRL_TRAIN_STEP_RETRAIN_CHECK :
HdmiFrlRetrainingCheckTimeout(frl);
break;
case HDMI_FRL_TRAIN_STEP_TRAIN_STOP :
HdmiFrlTrainingStop(frl);
break;
default :
break;
}
}
void HdmiFrlEnable(struct HdmiFrl *frl, bool enable)
{
if (frl == NULL || frl->priv == NULL) {
return;
}
frl->info.start = enable;
frl->info.machineInfo.start = enable;
frl->info.machineInfo.machineState = (enable == true) ? HDMI_FRL_STATE_MACHINE_START : HDMI_FRL_STATE_MACHINE_STOP;
frl->info.ctsMode = HdmiFrlIsCtsMode(frl);
if (frl->info.ctsMode == true) {
HdmiFrlGetCurRate(frl);
HDF_LOGD("frl cur rate %d", frl->info.curFrlRate);
}
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_READR_CHECK);
}
int32_t HdmiFrlModeSelect(struct HdmiFrl *frl)
{
int32_t ret;
struct HdmiCntlr *cntlr = NULL;
struct HdmiVideoAttr *videoAttr = NULL;
if (frl == NULL || frl->priv == NULL) {
return HDF_ERR_INVALID_PARAM;
}
ret = HdmiFrlCheckFrlCapability(frl);
if (ret == HDF_FAILURE) {
return ret;
} else if (ret != HDF_SUCCESS) {
HDF_LOGD("frl check capability fail, change to TMDS.");
frl->info.mode = HDMI_FRL_MODE_TMDS;
} else {
if (HdnmiFrlCheckFrlMode(frl) == true) {
HDF_LOGD("frl check frl mode succ.");
frl->info.mode = HDMI_FRL_MODE_FRL;
} else {
HDF_LOGD("frl check frl mode fail, change to TMDS.");
frl->info.mode = HDMI_FRL_MODE_TMDS;
}
}
cntlr = (struct HdmiCntlr *)frl->priv;
videoAttr = &(cntlr->attr.videoAttr);
if (frl->info.mode == HDMI_FRL_MODE_TMDS) {
if (videoAttr->tmdsClock > HDMI_HDMI20_MAX_TMDS_RATE) {
HDF_LOGE("FRL mode select, tmds Clock exceed max.");
return HDF_FAILURE;
}
if (HdmiEdidScdcSupport(cntlr->hdmi) == true) {
HdmiFrlSetTrainRate(frl);
}
return HDF_SUCCESS;
}
/* FRL mode. */
frl->info.curFrlRate = (frl->info.rateSelect == HDMI_FRL_RATE_BIG) ?
frl->info.maxFrlRate : frl->info.minFrlRate;
cntlr->tmdsMode = HDMI_TMDS_MODE_HDMI_2_0;
if (cntlr->ops != NULL && cntlr->ops->tmdsModeSet != NULL) {
HdmiCntlrLock(cntlr);
cntlr->ops->tmdsModeSet(cntlr, cntlr->tmdsMode);
HdmiCntlrUnlock(cntlr);
}
frl->info.ctsMode = false;
return HDF_SUCCESS;
}
bool HdmiFrlModeChanged(struct HdmiFrl *frl)
{
if (frl == NULL) {
return false;
}
if (frl->info.perMode != frl->info.mode) {
frl->info.perMode = frl->info.mode;
return true;
}
return false;
}
bool HdmiFrlSupport(struct HdmiFrl *frl)
{
if (frl == NULL) {
return false;
}
if (frl->info.mode == HDMI_FRL_MODE_FRL) {
return true;
}
return false;
}
+463
View File
@@ -0,0 +1,463 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "hdf_log.h"
#include "hdmi_core.h"
#define HDF_LOG_TAG hdmi_hdcp_c
static int32_t HdmiHdcpRead(struct HdmiHdcp *hdcp, enum HdmiHdcpPortOffset offset, uint8_t *buffer, uint32_t len)
{
struct HdmiDdcCfg cfg = {0};
struct HdmiCntlr *cntlr = NULL;
if (hdcp == NULL || hdcp->priv == NULL) {
return HDF_ERR_INVALID_PARAM;
}
cntlr = (struct HdmiCntlr *)hdcp->priv;
cfg.type = HDMI_DDC_DEV_HDCP;
cfg.readFlag = true;
cfg.devAddr = HDMI_DDC_HDCP_DEV_ADDRESS;
cfg.data = buffer;
cfg.dataLen = len;
cfg.offset = offset;
cfg.mode = HDMI_DDC_MODE_READ_MUTIL_NO_ACK;
return HdmiDdcTransfer(&(cntlr->ddc), &cfg);
}
static int32_t HdmiHdcpWrite(struct HdmiHdcp *hdcp, enum HdmiHdcpPortOffset offset, uint8_t *buffer, uint32_t len)
{
struct HdmiDdcCfg cfg = {0};
struct HdmiCntlr *cntlr = NULL;
if (hdcp == NULL || hdcp->priv == NULL) {
return HDF_ERR_INVALID_PARAM;
}
cntlr = (struct HdmiCntlr *)hdcp->priv;
cfg.type = HDMI_DDC_DEV_HDCP;
cfg.readFlag = false;
cfg.devAddr = HDMI_DDC_HDCP_DEV_ADDRESS;
cfg.data = buffer;
cfg.dataLen = len;
cfg.offset = offset;
cfg.mode = HDMI_DDC_MODE_WRITE_MUTIL_ACK;
return HdmiDdcTransfer(&(cntlr->ddc), &cfg);
}
static bool HdmiHdcpCheckKvs(uint8_t *ksv, uint32_t len)
{
uint32_t i, j;
uint32_t cnt = 0;
for (i = 0; i < len; i++) {
for (j = 0; j < HDMI_ONE_BYTE_SHIFT; j++) {
if (((ksv[i] >> j) & 0x01) > 0) {
cnt++;
}
}
}
/* KSV contains 20 ones and 20 zeros. */
if (cnt != HDMI_HDCP_AKSV_ONE_NUM) {
HDF_LOGE("HdmiHdcpCheckKvs: cnt = %d.", cnt);
return false;
}
return true;
}
static int32_t HdmiHdcpWriteMsgToReg(struct HdmiHdcp *hdcp, enum HdmiHdcpRegOptType type, uint8_t *data, uint32_t len)
{
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)hdcp->priv;
if (cntlr->ops == NULL || cntlr->ops->hdcpOptReg == NULL) {
HDF_LOGD("not support hdcp write reg.");
return HDF_ERR_INVALID_PARAM;
}
return cntlr->ops->hdcpOptReg(cntlr, type, data, len);
}
static int32_t HdmiHdcpReadMsgBksv(struct HdmiHdcp *hdcp)
{
int32_t ret;
ret = HdmiHdcpRead(hdcp, HDMI_HDCP_BKSV, hdcp->bksv, sizeof(hdcp->bksv));
if (ret != HDF_SUCCESS) {
return ret;
}
if (HdmiHdcpCheckKvs(hdcp->bksv, sizeof(hdcp->bksv)) == false) {
HDF_LOGE("auth part I: bksv check fail.");
return HDF_ERR_INVALID_PARAM;
}
return HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_WRITE_BKSV, hdcp->bksv, sizeof(hdcp->bksv));
}
static int32_t HdmiHdcpReadMsgRi(struct HdmiHdcp *hdcp)
{
int32_t ret;
ret = HdmiHdcpRead(hdcp, HDMI_HDCP_RI, hdcp->ri, sizeof(hdcp->ri));
if (ret != HDF_SUCCESS) {
return ret;
}
return HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_WRITE_RI, hdcp->ri, sizeof(hdcp->ri));
}
static int32_t HdmiHdcpWriteMsgAksv(struct HdmiHdcp *hdcp)
{
if (HdmiHdcpCheckKvs(hdcp->aksv, sizeof(hdcp->aksv)) == false) {
HDF_LOGE("auth part I: aksv check fail.");
return HDF_ERR_INVALID_PARAM;
}
return HdmiHdcpWrite(hdcp, HDMI_HDCP_AN, hdcp->aksv, sizeof(hdcp->aksv));
}
static int32_t HdmiHdcpWriteMsgAn(struct HdmiHdcp *hdcp)
{
return HdmiHdcpWrite(hdcp, HDMI_HDCP_AN, hdcp->an, sizeof(hdcp->an));
}
static int32_t HdmiHdcpReadMsgHv(struct HdmiHdcp *hdcp)
{
uint8_t offset, i;
uint8_t vhNum = HDMI_HDCP_MSG_ALL_VH_LEN / HDMI_HDCP_MSG_PER_VH_LEN;
int32_t ret;
if (hdcp == NULL) {
return HDF_ERR_INVALID_PARAM;
}
for (i = 0; i < vhNum; i++) {
offset = HDMI_HDCP_V_H0 + i * HDMI_HDCP_MSG_PER_VH_LEN;
ret = HdmiHdcpRead(hdcp, offset, &(hdcp->vh[i]), HDMI_HDCP_MSG_PER_VH_LEN);
if (ret != HDF_SUCCESS) {
return ret;
}
}
return HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_WRITE_V_H_ALL, hdcp->vh, sizeof(hdcp->vh));
}
static int32_t HdmiHdcpReadMsgBcaps(struct HdmiHdcp *hdcp)
{
int32_t ret;
ret = HdmiHdcpRead(hdcp, HDMI_HDCP_BCAPS, &(hdcp->bcaps), sizeof(hdcp->bcaps));
if (ret != HDF_SUCCESS) {
return ret;
}
return HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_WRITE_BCAPS, &(hdcp->bcaps), sizeof(hdcp->bcaps));
}
static int32_t HdmiHdcpAuthenticationGenerateAksvAn(struct HdmiHdcp *hdcp)
{
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)hdcp->priv;
if (cntlr->ops == NULL || cntlr->ops->hdcpGenerateAksvAndAn == NULL) {
return HDF_ERR_NOT_SUPPORT;
}
return cntlr->ops->hdcpGenerateAksvAndAn(cntlr);
}
static void HdmiHdcpRegPrepare(struct HdmiHdcp *hdcp)
{
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)hdcp->priv;
if (cntlr->ops == NULL || cntlr->ops->hdcpRegInit == NULL) {
return;
}
cntlr->ops->hdcpRegInit(cntlr);
}
static int32_t HdmiHdcpAuthenticationPrepare(struct HdmiHdcp *hdcp)
{
int32_t ret;
HdmiHdcpRegPrepare(hdcp);
if (hdcp->aksvValid == false) {
ret = HdmiHdcpAuthenticationGenerateAksvAn(hdcp);
if (ret != HDF_SUCCESS) {
hdcp->state = HDMI_HDCP_AUTH_AKSV_INVALID;
return ret;
}
}
hdcp->aksvValid = true;
return HDF_SUCCESS;
}
static int32_t HdmiHdcpAuthenticationFirstPart(struct HdmiHdcp *hdcp)
{
int32_t ret;
hdcp->state = HDMI_HDCP_AUTH_DOING;
/*
* Authentication is initiated by the HDCP Transmitter by sendind an initiation massage containing its KSV(aksv)
* and a 64-bit pseudo-random value(An) generated by the HDCP Cipher function hdcpRngCipher to the HDCP Reciever.
*/
ret = HdmiHdcpWriteMsgAksv(hdcp);
if (ret != HDF_SUCCESS) {
return ret;
}
ret = HdmiHdcpWriteMsgAn(hdcp);
if (ret != HDF_SUCCESS) {
return ret;
}
/*
* The HDCP Reciever responds by sending a response message containing the receiver's KSV(bksv) and
* the REPEATER bit, which indicates if the reciever is an HDCP Repeater.
*/
ret = HdmiHdcpReadMsgBksv(hdcp);
if (ret != HDF_SUCCESS) {
return ret;
}
ret = HdmiHdcpReadMsgBcaps(hdcp);
if (ret != HDF_SUCCESS) {
return ret;
}
/*
* The HDCP Transmitter must not read the R0' value sooner than 100ms after writing Aksv.
*/
OsalMSleep(120);
/* Read R0' */
ret = HdmiHdcpReadMsgRi(hdcp);
if (ret != HDF_SUCCESS) {
return ret;
}
/* Verify R0/R0' matched or not */
ret = HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_CHECK_R, NULL, 0);
if (ret != HDF_SUCCESS) {
HDF_LOGE("hdcp auth, check V fail.");
return ret;
}
return HDF_SUCCESS;
}
static int32_t HdmiHdcpAuthenticationCheckBstatus(struct HdmiHdcp *hdcp)
{
int32_t ret;
uint16_t bstatus;
bool maxDevExceeded, maxCascadeExceeded;
ret = HdmiHdcpRead(hdcp, HDMI_HDCP_BSTATUS, hdcp->bstatus, sizeof(hdcp->bstatus));
if (ret != HDF_SUCCESS) {
return ret;
}
/* phase bstatus. */
bstatus = (hdcp->bstatus[1] << 8) | hdcp->bstatus[0];
hdcp->deviceCount = bstatus & HDMI_HDCP_BSTATUS_DEVICE_COUNT_MARK;
maxDevExceeded = (bstatus & HDMI_HDCP_BSTATUS_MAX_DEVS_EXCEEDED_MARK) ? true : false;
maxCascadeExceeded = (bstatus & HDMI_HDCP_BSTATUS_MAX_CASCADE_EXCEEDED_MARK) ? true : false;
if (hdcp->deviceCount == 0) {
HDF_LOGE("hdcp auth, check bstatus, no device attached to the repeater.");
return HDF_DEV_ERR_NO_DEVICE;
}
if (maxDevExceeded == true) {
HDF_LOGE("hdcp auth, check bstatus, exceeds max allowed connected devices.");
return HDF_ERR_IO;
}
if (maxCascadeExceeded == true) {
HDF_LOGE("hdcp auth, check bstatus, exceeds max allowed cascade.");
return HDF_ERR_IO;
}
return HDF_SUCCESS;
}
static int32_t HdmiHdcpAuthenticationWaitKsvListReady(struct HdmiHdcp *hdcp)
{
uint32_t i;
int32_t ret;
bool ready = false;
/* Set up 5s timer, poll for KSV list ready. Fail if timer expires prior to ready. */
for (i = 0; i < HDMI_HDCP_WAIT_KSV_LIST_READ_REG_CNT; i++) {
ret = HdmiHdcpRead(hdcp, HDMI_HDCP_BCAPS, &(hdcp->bcaps), sizeof(hdcp->bcaps));
if (ret != HDF_SUCCESS) {
return ret;
}
if ((hdcp->bcaps & HDMI_HDCP_BCAPS_KSV_FIFO_READY_MARK) > 0) {
ready = true;
break;
}
OsalMSleep(HDMI_HDCP_WAIT_KSV_LIST_READ_REG_INTERVAL);
}
if (ready == false) {
return HDF_ERR_TIMEOUT;
}
/* */
ret = HdmiHdcpAuthenticationCheckBstatus(hdcp);
if (ret != HDF_SUCCESS) {
return ret;
}
(void)HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_WRITE_BCAPS, &(hdcp->bcaps), sizeof(hdcp->bcaps));
(void)HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_WRITE_BSTATUS, hdcp->bstatus, sizeof(hdcp->bstatus));
return HDF_SUCCESS;
}
static int32_t HdmiHdcpAuthenticationReadKsvList(struct HdmiHdcp *hdcp)
{
int32_t ret;
uint32_t try = HDMI_HDCP_DEFAULT_READ_REG_TRY;
hdcp->ksvLen = HDMI_HDCP_GET_KSV_LEN(hdcp->deviceCount);
do {
ret = HdmiHdcpRead(hdcp, HDMI_HDCP_KSV_FIFO, hdcp->ksvList, hdcp->ksvLen);
if (ret == HDF_SUCCESS) {
break;
}
OsalMSleep(HDMI_HDCP_WAIT_KSV_LIST_READ_REG_INTERVAL);
try--;
} while (try > 0);
ret = HdmiHdcpReadMsgHv(hdcp);
if (ret != HDF_SUCCESS) {
return ret;
}
/* We may need to reset SHA before write ksv list. */
(void)HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_RESET_SHA, NULL, 0);
(void)HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_WRITE_KSV_FIFO, hdcp->ksvList, hdcp->ksvLen);
return HDF_SUCCESS;
}
static int32_t HdmiHdcpAuthenticationSecondPart(struct HdmiHdcp *hdcp)
{
int32_t ret;
/* Poll: KSV list ready. */
ret = HdmiHdcpAuthenticationWaitKsvListReady(hdcp);
if (ret != HDF_SUCCESS) {
HDF_LOGE("hdcp auth, wait ksv list ready fail.");
return ret;
}
/* Read KSV list */
ret = HdmiHdcpAuthenticationReadKsvList(hdcp);
if (ret != HDF_SUCCESS) {
HDF_LOGE("hdcp auth, read ksv list fail.");
return ret;
}
/* Verify V/V' matched or not */
ret = HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_CHECK_V, NULL, 0);
if (ret != HDF_SUCCESS) {
HDF_LOGE("hdcp auth, check V fail.");
return ret;
}
return HDF_SUCCESS;
}
static void HdmiHdcpAuthenticationSucc(struct HdmiHdcp *hdcp)
{
(void)HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_AUTH_DONE, NULL, 0);
hdcp->state = HDMI_HDCP_AUTH_DONE;
hdcp->authRetryCnt = 0;
}
static void HdmiHdcpAuthenticationFail(struct HdmiHdcp *hdcp)
{
(void)HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_AUTH_FAIL, NULL, 0);
hdcp->state = HDMI_HDCP_AUTH_FAIL;
}
static int32_t HdmiHdcpAuthentication(struct HdmiHdcp *hdcp)
{
int32_t ret;
if (hdcp == NULL || hdcp->priv == NULL) {
return HDF_ERR_INVALID_PARAM;
}
/* auth prepare, get aksv and driver clear registers. */
ret = HdmiHdcpAuthenticationPrepare(hdcp);
if (ret != HDF_SUCCESS) {
goto _END;
}
/*
* First part of the authentication exchange.
*/
ret = HdmiHdcpAuthenticationFirstPart(hdcp);
if (ret != HDF_SUCCESS) {
goto _END;
}
HDF_LOGD("hdcp auth Part I success.");
/* receiver (0), repeater (1) */
if ((hdcp->bcaps & HDMI_HDCP_BCAPS_REPEATER_MARK) == 0) {
goto _END;
}
/*
* The second part of the authentication protocol is required if the HDCP Reciever is an HDCP Repeater.
*/
ret = HdmiHdcpAuthenticationSecondPart(hdcp);
if (ret != HDF_SUCCESS) {
goto _END;
}
_END:
if (ret == HDF_SUCCESS) {
HdmiHdcpAuthenticationSucc(hdcp);
} else {
HdmiHdcpAuthenticationFail(hdcp);
}
return ret;
}
static int32_t HdmiHdcpAuthenticationRetry(struct HdmiHdcp *hdcp)
{
if (hdcp == NULL || hdcp->priv == NULL) {
return HDF_ERR_INVALID_PARAM;
}
if (hdcp->authRetryCnt > HDMI_HDCP_AUTH_MAX_RETRY_CNT) {
HDF_LOGE("hdcp auth reach to max cnt, auth fail");
return HDF_FAILURE;
}
return HdmiHdcpAuthentication(hdcp);
}
int32_t HdmiHdcpOpen(struct HdmiHdcp *hdcp)
{
int32_t ret;
(void)OsalMutexLock(&(hdcp->hdcpMutex));
hdcp->state = HDMI_HDCP_AUTH_INACTIVE;
hdcp->authRetryCnt = 0;
ret = HdmiHdcpAuthentication(hdcp);
if (ret == HDF_SUCCESS) {
HDF_LOGD("hdcp Authentication success!");
goto __END;
}
while (hdcp->authRetryCnt <= HDMI_HDCP_AUTH_MAX_RETRY_CNT) {
ret = HdmiHdcpAuthenticationRetry(hdcp);
if (ret == HDF_SUCCESS) {
goto __END;
}
hdcp->authRetryCnt++;
}
__END :
(void)OsalMutexUnlock(&(hdcp->hdcpMutex));
return ret;
}
void HdmiHdcpClose(struct HdmiHdcp *hdcp)
{
if (hdcp == NULL) {
return;
}
if (hdcp->state == HDMI_HDCP_AUTH_INACTIVE ||
hdcp->state == HDMI_HDCP_AUTH_AKSV_INVALID) {
return;
}
(void)HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_AUTH_CLOSE, NULL, 0);
hdcp->state = HDMI_HDCP_AUTH_INACTIVE;
hdcp->authRetryCnt = 0;
}
+273
View File
@@ -0,0 +1,273 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "hdf_log.h"
#include "hdmi_core.h"
#define HDF_LOG_TAG hdmi_hdr_c
static bool HdmiHdrAttrChange(struct HdmiHdrAttr *curAttr, struct HdmiHdrAttr *oldAttr)
{
if (memcmp(curAttr, oldAttr, sizeof(struct HdmiHdrAttr)) == 0) {
return false;
}
return true;
}
static void HdmiHdrColorimetryUpdate(struct HdmiVideoAttr *videoAttr, enum HdmiHdrColormetry colorimetry)
{
if (colorimetry >= HDMI_HDR_COLORIMETRY_EXTENDED) {
videoAttr->colorimetry = HDMI_COLORIMETRY_EXTENDED;
videoAttr->extColorimetry = (enum HdmiExtendedColorimetry)(colorimetry -
HDMI_HDR_EXTENDED_COLORIMETRY_XV_YCC_601);
} else {
videoAttr->colorimetry = (enum HdmiColorimetry)colorimetry;
videoAttr->extColorimetry = HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
}
}
static void HdmiHdrZeroDrmInfoframeTimerSet(struct HdmiCntlr *cntlr, bool start)
{
struct HdmiHdrInfo *hdrInfo = &(cntlr->hdr->info);
struct HdmiHdrAttr *hdrAttr = &(cntlr->attr.hdrAttr);
hdrInfo->zeroDrmIfTimer.start = false;
hdrInfo->zeroDrmIfTimer.timerType = HDMI_HDR_TIMER_ZERO_DRMIF;
hdrInfo->zeroDrmIfTimer.time = HDMI_ZERO_DRMIF_SEND_TIME;
HdmiCntlrHdrTimerSet(cntlr, &(hdrInfo->zeroDrmIfTimer));
if (start == false) {
return;
}
hdrAttr->eotfType = HDMI_DRM_EOTF_SDR_LUMIN;
hdrAttr->metadataType = HDMI_DRM_STATIC_METADATA_TYPE_1;
if (memset_s(&(hdrAttr->descriptor), sizeof(hdrAttr->descriptor), 0, sizeof(hdrAttr->descriptor)) != EOK) {
HDF_LOGE("memset_s fail");
return;
}
(void)HdmiDrmInfoframeSend(&(cntlr->infoframe), true);
hdrInfo->zeroDrmIfTimer.start = true;
HdmiCntlrHdrTimerSet(cntlr, &(hdrInfo->zeroDrmIfTimer));
}
static void HdmiHdrModeChangeTimerSet(struct HdmiCntlr *cntlr, bool start)
{
struct HdmiHdrInfo *hdrInfo = &(cntlr->hdr->info);
hdrInfo->stateChangeTimer.start = false;
hdrInfo->stateChangeTimer.timerType = HDMI_HDR_TIMER_SDR_TO_HDR10;
hdrInfo->stateChangeTimer.time = HDMI_HDR_STATE_CHANGE_TIME;
HdmiCntlrHdrTimerSet(cntlr, &(hdrInfo->stateChangeTimer));
if (start == false) {
return;
}
hdrInfo->stateChangeTimer.start = true;
HdmiCntlrHdrTimerSet(cntlr, &(hdrInfo->stateChangeTimer));
}
static int32_t HdmiDisableHdr(struct HdmiCntlr *cntlr, struct HdmiHdrAttr *curAttr)
{
int32_t ret = HDF_SUCCESS;
struct HdmiHdrAttr *oldAttr = &(cntlr->attr.hdrAttr);
struct HdmiVideoAttr *videoAttr = &(cntlr->attr.videoAttr);
struct HdmiCommonAttr *commAttr = &(cntlr->attr.commAttr);
struct HdmiHdrInfo *hdrInfo = &(cntlr->hdr->info);
switch (oldAttr->mode) {
case HDMI_HDR_MODE_DISABLE:
break;
case HDMI_HDR_MODE_CEA_861_3:
*oldAttr = *curAttr;
if (hdrInfo->state != HDMI_HDR_STATE_NONE) {
/* to solve the problem of some TV can not switch smoothly from HDR10 to non-HDR10. */
if (hdrInfo->state == HDMI_HDR_STATE_OE) {
HdmiCntlrAudioMuteEnable(cntlr, false);
HdmiCntlrBlackDataSet(cntlr, true);
}
HdmiCntlrAvmuteSet(cntlr, true);
if (hdrInfo->state == HDMI_HDR_STATE_OE) {
HdmiCntlrPhyOutputEnablet(cntlr, false);
}
HdmiHdrModeChangeTimerSet(cntlr, true);
HdmiCntlrHdrTimerSet(cntlr, &(hdrInfo->stateChangeTimer));
(void)HdmiDrmInfoframeSend(&(cntlr->infoframe), false);
} else {
/* start timer, send zero DRMIF and stop after 2 seconds. */
HdmiHdrZeroDrmInfoframeTimerSet(cntlr, true);
}
break;
case HDMI_HDR_MODE_CEA_861_3_AUTHEN:
case HDMI_HDR_MODE_DOLBY_NORMAL:
case HDMI_HDR_MODE_DOLBY_TUNNELING:
if (oldAttr->mode != HDMI_HDR_MODE_DOLBY_NORMAL) {
commAttr->colorSpace = HDMI_COLOR_SPACE_YCBCR444;
}
videoAttr->quantization = HDMI_QUANTIZATION_RANGE_DEFAULT;
videoAttr->yccQuantization = HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
break;
default:
ret = HDF_FAILURE;
break;
}
return ret;
}
static void HdmiChangeToHdr(struct HdmiCntlr *cntlr, struct HdmiCommonAttr *commAttr)
{
struct HdmiHdrAttr *hdrAttr = &(cntlr->attr.hdrAttr);
struct HdmiHdrInfo *hdrInfo = &(cntlr->hdr->info);
HdmiHdrZeroDrmInfoframeTimerSet(cntlr,false);
if (hdrAttr->userMode != HDMI_HDR_USERMODE_HDR10) {
HDF_LOGE("usermode is not HDR10/HLG.");
return;
}
commAttr->drm = true;
if (hdrInfo->state != HDMI_HDR_STATE_NONE) {
/* to solve the problem of some TV can not switch smoothly from non-HDR10 to HDR10. */
if (hdrInfo->state == HDMI_HDR_STATE_OE) {
HdmiCntlrAudioMuteEnable(cntlr, false);
HdmiCntlrBlackDataSet(cntlr, true);
}
HdmiCntlrAvmuteSet(cntlr, true);
if (hdrInfo->state == HDMI_HDR_STATE_OE) {
HdmiCntlrPhyOutputEnablet(cntlr, false);
}
hdrInfo->stateChangeTimer.start = true;
hdrInfo->stateChangeTimer.timerType = HDMI_HDR_TIMER_SDR_TO_HDR10;
hdrInfo->stateChangeTimer.time = HDMI_HDR_STATE_CHANGE_TIME;
HdmiCntlrHdrTimerSet(cntlr, &(hdrInfo->stateChangeTimer));
}
}
static int32_t HdmiHdrModeSelect(struct HdmiCntlr *cntlr)
{
struct HdmiHdrAttr *hdrAttr = &(cntlr->attr.hdrAttr);
struct HdmiCommonAttr *commAttr = &(cntlr->attr.commAttr);
switch (hdrAttr->mode) {
case HDMI_HDR_MODE_CEA_861_3:
HdmiChangeToHdr(cntlr, commAttr);
commAttr->vsifDolby = false;
break;
case HDMI_HDR_MODE_CEA_861_3_AUTHEN:
/* HDR10 authen mode, HDMI must bypass. */
if (hdrAttr->userMode != HDMI_HDR_USERMODE_DOLBY) {
HDF_LOGE("user mode is not dolby");
return HDF_FAILURE;
}
commAttr->drm = true;
commAttr->vsifDolby = false;
break;
case HDMI_HDR_MODE_DOLBY_NORMAL:
case HDMI_HDR_MODE_DOLBY_TUNNELING:
if (hdrAttr->userMode != HDMI_HDR_USERMODE_DOLBY) {
HDF_LOGE("user mode is not dolby");
return HDF_FAILURE;
}
commAttr->drm = false;
commAttr->vsifDolby = true;
break;
default:
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
int32_t HdmiHdrAttrHandle(struct HdmiHdr *hdr, struct HdmiHdrAttr *curAttr)
{
struct HdmiHdrAttr *oldAttr = NULL;
struct HdmiCommonAttr *commAttr = NULL;
struct HdmiCntlr *cntlr = NULL;
int32_t ret = HDF_FAILURE;
if (hdr == NULL || hdr->priv == NULL) {
HDF_LOGE("hdr attr handle, input param invalid.");
return HDF_ERR_INVALID_PARAM;
}
cntlr = (struct HdmiCntlr *)hdr->priv;
oldAttr = &(cntlr->attr.hdrAttr);
commAttr = &(cntlr->attr.commAttr);
if (HdmiHdrAttrChange(curAttr, oldAttr) == false) {
HDF_LOGD("hdr attr not change");
return HDF_SUCCESS;
}
if (oldAttr->colorimetry != curAttr->colorimetry) {
HdmiHdrColorimetryUpdate(&(cntlr->attr.videoAttr), curAttr->colorimetry);
}
/* change to SDR */
if (curAttr->mode == HDMI_HDR_MODE_DISABLE) {
if (HdmiDisableHdr(cntlr, curAttr) == HDF_SUCCESS) {
commAttr->vsifDolby = false;
cntlr->attr.hdrAttr = *curAttr;
goto _SEND_INFOFRAME;
} else {
return HDF_FAILURE;
}
}
/* change to HDR */
cntlr->attr.hdrAttr = *curAttr;
ret = HdmiHdrModeSelect(cntlr);
if (ret != HDF_SUCCESS) {
return ret;
}
(void)HdmiDrmInfoframeSend(&(cntlr->infoframe), (commAttr->enableHdmi & commAttr->drm));
_SEND_INFOFRAME:
(void)HdmiAviInfoframeSend(&(cntlr->infoframe), (commAttr->enableHdmi && commAttr->avi));
(void)HdmiVsInfoframeSend(&(cntlr->infoframe), commAttr->enableHdmi, commAttr->vsifDolby);
HdmiCntlrVideoPathSet(cntlr, &(cntlr->attr.videoAttr));
return ret;
}
int32_t HdmiHdrDrmInfoframeStop(struct HdmiHdr *hdr)
{
struct HdmiCntlr *cntlr = NULL;
HDF_LOGD("zero DRM infoframe send timeout.");
if (hdr == NULL || hdr->priv == NULL) {
HDF_LOGE("hdr stop drm, input param invalid.");
return HDF_ERR_INVALID_PARAM;
}
cntlr = (struct HdmiCntlr *)hdr->priv;
if (cntlr->attr.hdrAttr.mode != HDMI_HDR_MODE_CEA_861_3) {
return HdmiDrmInfoframeSend(&(cntlr->infoframe), false);
}
return HDF_SUCCESS;
}
int32_t HdmiHdrModeChangeTimeout(struct HdmiHdr *hdr)
{
struct HdmiCntlr *cntlr = NULL;
HDF_LOGD("hdr mode change timeout.");
if (hdr == NULL || hdr->priv == NULL) {
HDF_LOGE("hdr mode change timeout, input param invalid.");
return HDF_ERR_INVALID_PARAM;
}
cntlr = (struct HdmiCntlr *)hdr->priv;
if (hdr->info.state == HDMI_HDR_STATE_OE) {
HdmiCntlrPhyOutputEnablet(cntlr, true);
}
HdmiCntlrAvmuteSet(cntlr, false);
if (hdr->info.state == HDMI_HDR_STATE_OE) {
HdmiCntlrBlackDataSet(cntlr, false);
HdmiCntlrAudioMuteEnable(cntlr, true);
}
return HDF_SUCCESS;
}
+494
View File
@@ -0,0 +1,494 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "hdmi_if.h"
#ifndef __USER__
#include "hdmi_core.h"
#endif
#include "hdf_base.h"
#include "hdf_log.h"
#include "osal_mem.h"
#ifdef __USER__
#include "hdf_io_service_if.h"
#include "securec.h"
#endif
#define HDF_LOG_TAG hdmi_if_c
#define HDMI_SERVICE_NAME_LEN 32
#ifdef __USER__
enum HdmiIoCmd {
HDMI_CMD_OPEN,
HDMI_CMD_CLOSE,
HDMI_CMD_START,
HDMI_CMD_STOP,
HDMI_CMD_AVMUTE_SET,
HDMI_CMD_DEEP_COLOR_SET,
HDMI_CMD_DEEP_COLOR_GET,
HDMI_CMD_VIDEO_ATTR_SET,
HDMI_CMD_AUDIO_ATTR_SET,
HDMI_CMD_HDR_ATTR_SET,
HDMI_CMD_READ_SINK_EDID,
HDMI_CMD_INFOFRAME_SET,
HDMI_CMD_INFOFRAME_GET,
HDMI_CMD_BUTT,
};
static int32_t HdmiGetDataFromReply(struct HdfSBuf *reply, uint8_t *data, uint32_t size)
{
uint32_t rLen;
const void *rBuf = NULL;
if (HdfSbufReadBuffer(reply, &rBuf, &rLen) == false) {
HDF_LOGE("HdmiGetDataFromReply: read rBuf fail!");
return HDF_ERR_IO;
}
if (size != rLen) {
HDF_LOGE("HdmiGetDataFromReply: err len:%u, rLen:%u", size, rLen);
if (rLen > size) {
rLen = size;
}
}
if (memcpy_s(data, size, rBuf, rLen) != EOK) {
HDF_LOGE("HdmiGetDataFromReply: memcpy rBuf fail!");
return HDF_ERR_IO;
}
return HDF_SUCCESS;
}
static void HdmiUserClose(DevHandle handle)
{
struct HdfIoService *service = (struct HdfIoService *)handle;
int32_t ret;
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
HDF_LOGE("HdmiUserClose: service is invalid");
return;
}
ret = service->dispatcher->Dispatch(&service->object, HDMI_CMD_CLOSE, NULL, NULL);
if (ret != HDF_SUCCESS) {
HDF_LOGE("HdmiUserClose: failed to send service call:%d", ret);
}
}
static int32_t HdmiUserStart(DevHandle handle)
{
struct HdfIoService *service = (struct HdfIoService *)handle;
int32_t ret;
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
HDF_LOGE("HdmiUserStart: service is invalid");
return HDF_ERR_INVALID_PARAM;
}
ret = service->dispatcher->Dispatch(&service->object, HDMI_CMD_START, NULL, NULL);
if (ret != HDF_SUCCESS) {
HDF_LOGE("HdmiUserStart: failed to send service call:%d", ret);
return ret;
}
return HDF_SUCCESS;
}
static int32_t HdmiUserStop(DevHandle handle)
{
struct HdfIoService *service = (struct HdfIoService *)handle;
int32_t ret;
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
HDF_LOGE("HdmiUserStop: service is invalid");
return HDF_ERR_INVALID_PARAM;
}
ret = service->dispatcher->Dispatch(&service->object, HDMI_CMD_STOP, NULL, NULL);
if (ret != HDF_SUCCESS) {
HDF_LOGE("HdmiUserStop: failed to send service call:%d", ret);
return ret;
}
return HDF_SUCCESS;
}
static int32_t HdmiUserAvmuteSet(DevHandle handle, bool enable)
{
int32_t ret;
struct HdfSBuf *buf = NULL;
struct HdfIoService *service = (struct HdfIoService *)handle;
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
HDF_LOGE("HdmiUserAvmuteSet: service is invalid");
return HDF_ERR_INVALID_PARAM;
}
buf = HdfSBufObtain(sizeof(enable));
if (buf == NULL) {
HDF_LOGE("HdmiUserAvmuteSet: failed to obtain buf");
return HDF_ERR_MALLOC_FAIL;
}
if (!HdfSbufWriteBuffer(buf, &enable, sizeof(enable))) {
HDF_LOGE("HdmiUserAvmuteSet: sbuf write buffer failed");
HdfSBufRecycle(buf);
return HDF_ERR_IO;
}
ret = service->dispatcher->Dispatch(&service->object, HDMI_CMD_AVMUTE_SET, buf, NULL);
if (ret != HDF_SUCCESS) {
HDF_LOGE("HdmiUserAvmuteSet: failed to write, ret %d", ret);
}
HdfSBufRecycle(buf);
return ret;
}
static int32_t HdmiUserDeepColorSet(DevHandle handle, enum HdmiDeepColor color)
{
int32_t ret;
struct HdfSBuf *buf = NULL;
struct HdfIoService *service = (struct HdfIoService *)handle;
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
HDF_LOGE("HdmiUserDeepColorSet: service is invalid");
return HDF_ERR_INVALID_PARAM;
}
buf = HdfSBufObtain(sizeof(color));
if (buf == NULL) {
HDF_LOGE("HdmiUserDeepColorSet: failed to obtain buf");
return HDF_ERR_MALLOC_FAIL;
}
if (!HdfSbufWriteBuffer(buf, &color, sizeof(color))) {
HDF_LOGE("HdmiUserDeepColorSet: sbuf write color failed");
HdfSBufRecycle(buf);
return HDF_ERR_IO;
}
ret = service->dispatcher->Dispatch(&service->object, HDMI_CMD_DEEP_COLOR_SET, buf, NULL);
if (ret != HDF_SUCCESS) {
HDF_LOGE("HdmiUserDeepColorSet: failed to write, ret %d", ret);
}
HdfSBufRecycle(buf);
return ret;
}
static int32_t HdmiUserSetVideoAttribute(DevHandle handle, struct HdmiVideoAttr *attr)
{
int32_t ret;
struct HdfSBuf *buf = NULL;
struct HdfIoService *service = (struct HdfIoService *)handle;
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
HDF_LOGE("HdmiUserSetVideoAttribute: service is invalid");
return HDF_ERR_INVALID_PARAM;
}
if (attr == NULL) {
return HDF_ERR_INVALID_PARAM;
}
buf = HdfSBufObtain(sizeof(struct HdmiVideoAttr));
if (buf == NULL) {
HDF_LOGE("HdmiUserSetVideoAttribute: failed to obtain buf");
return HDF_ERR_MALLOC_FAIL;
}
if (!HdfSbufWriteBuffer(buf, attr, sizeof(struct HdmiVideoAttr))) {
HDF_LOGE("HdmiUserSetVideoAttribute: sbuf write attr failed");
HdfSBufRecycle(buf);
return HDF_ERR_IO;
}
ret = service->dispatcher->Dispatch(&service->object, HDMI_CMD_VIDEO_ATTR_SET, buf, NULL);
if (ret != HDF_SUCCESS) {
HDF_LOGE("HdmiUserSetVideoAttribute: failed to write, ret %d", ret);
}
HdfSBufRecycle(buf);
return ret;
}
static int32_t HdmiUserSetAudioAttribute(DevHandle handle, struct HdmiAudioAttr *attr)
{
int32_t ret;
struct HdfSBuf *buf = NULL;
struct HdfIoService *service = (struct HdfIoService *)handle;
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
HDF_LOGE("HdmiUserSetAudioAttribute: service is invalid");
return HDF_ERR_INVALID_PARAM;
}
if (attr == NULL) {
HDF_LOGE("HdmiUserSetAudioAttribute: attr is NULL");
return HDF_ERR_INVALID_PARAM;
}
buf = HdfSBufObtain(sizeof(struct HdmiAudioAttr));
if (buf == NULL) {
HDF_LOGE("HdmiUserSetAudioAttribute: failed to obtain buf");
return HDF_ERR_MALLOC_FAIL;
}
if (!HdfSbufWriteBuffer(buf, attr, sizeof(struct HdmiAudioAttr))) {
HDF_LOGE("HdmiUserSetAudioAttribute: sbuf write attr failed");
HdfSBufRecycle(buf);
return HDF_ERR_IO;
}
ret = service->dispatcher->Dispatch(&service->object, HDMI_CMD_AUDIO_ATTR_SET, buf, NULL);
if (ret != HDF_SUCCESS) {
HDF_LOGE("HdmiUserSetAudioAttribute: failed to write, ret %d", ret);
}
HdfSBufRecycle(buf);
return ret;
}
static int32_t HdmiUserSetHdrAttribute(DevHandle handle, struct HdmiHdrAttr *attr)
{
int32_t ret;
struct HdfSBuf *buf = NULL;
struct HdfIoService *service = (struct HdfIoService *)handle;
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
HDF_LOGE("HdmiUserSetHdrAttribute: service is invalid");
return HDF_ERR_INVALID_PARAM;
}
if (attr == NULL) {
HDF_LOGE("HdmiUserSetHdrAttribute: attr is NULL");
return HDF_ERR_INVALID_PARAM;
}
buf = HdfSBufObtain(sizeof(struct HdmiHdrAttr));
if (buf == NULL) {
HDF_LOGE("HdmiUserSetHdrAttribute: failed to obtain buf");
return HDF_ERR_MALLOC_FAIL;
}
if (!HdfSbufWriteBuffer(buf, attr, sizeof(struct HdmiHdrAttr))) {
HDF_LOGE("HdmiUserSetHdrAttribute: sbuf write attr failed");
HdfSBufRecycle(buf);
return HDF_ERR_IO;
}
ret = service->dispatcher->Dispatch(&service->object, HDMI_CMD_HDR_ATTR_SET, buf, NULL);
if (ret != HDF_SUCCESS) {
HDF_LOGE("HdmiUserSetAudioAttribute: failed to write, ret %d", ret);
}
HdfSBufRecycle(buf);
return ret;
}
static int32_t HdmiUserDeepColorGet(DevHandle handle, enum HdmiDeepColor *color)
{
int32_t ret;
struct HdfSBuf *reply = NULL;
struct HdfIoService *service = (struct HdfIoService *)handle;
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
HDF_LOGE("HdmiUserDeepColorGet: service is invalid");
return HDF_ERR_INVALID_PARAM;
}
if (color == NULL) {
return HDF_ERR_INVALID_PARAM;
}
/* Four bytes are used to store the buffer length, and four bytes are used to align the memory. */
reply = HdfSBufObtain(sizeof(*color) + sizeof(uint64_t));
if (reply == NULL) {
HDF_LOGE("HdmiUserDeepColorGet: failed to obtain reply");
ret = HDF_ERR_MALLOC_FAIL;
goto __EXIT;
}
ret = service->dispatcher->Dispatch(&service->object, HDMI_CMD_DEEP_COLOR_GET, NULL, reply);
if (ret != HDF_SUCCESS) {
HDF_LOGE("HdmiUserDeepColorGet: failed to write, ret %d", ret);
} else {
ret = HdmiGetDataFromReply(reply, (uint8_t *)color, sizeof(*color));
}
__EXIT :
if (reply != NULL) {
HdfSBufRecycle(reply);
}
return ret;
}
static int32_t HdmiUserGetSinkEdid(DevHandle handle, uint8_t *buffer, uint32_t len)
{
int32_t ret;
struct HdfSBuf *reply = NULL;
struct HdfIoService *service = (struct HdfIoService *)handle;
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
HDF_LOGE("HdmiUserGetSinkEdid: service is invalid");
return HDF_ERR_INVALID_PARAM;
}
if (buffer == NULL || len == 0) {
return HDF_ERR_INVALID_PARAM;
}
reply = HdfSBufObtain(len);
if (reply == NULL) {
HDF_LOGE("HdmiUserGetSinkEdid: failed to obtain reply");
ret = HDF_ERR_MALLOC_FAIL;
goto __EXIT;
}
ret = service->dispatcher->Dispatch(&service->object, HDMI_CMD_READ_SINK_EDID, NULL, reply);
if (ret <= 0) {
HDF_LOGE("HdmiUserGetSinkEdid: failed to write, ret %d", ret);
} else {
ret = HdmiGetDataFromReply(reply, buffer, len);
}
__EXIT :
if (reply != NULL) {
HdfSBufRecycle(reply);
}
return ret;
}
#endif
static void *HdmiCntlrObjGet(uint16_t busNum)
{
char *serviceName = NULL;
void *obj = NULL;
serviceName = (char *)OsalMemCalloc(HDMI_SERVICE_NAME_LEN + 1);
if (serviceName == NULL) {
HDF_LOGE("HDMI service name malloc fail.");
return NULL;
}
if (snprintf_s(serviceName, (HDMI_SERVICE_NAME_LEN + 1),
HDMI_SERVICE_NAME_LEN, "HDF_PLATFORM_HDMI_%d", busNum) < 0) {
HDF_LOGE("get HDMI service name fail.");
goto __ERR;
}
#ifdef __USER__
obj = (void *)HdfIoServiceBind(serviceName);
#else
obj = (void *)HdmiCntlrGetByBusNum(busNum);
#endif
__ERR:
OsalMemFree(serviceName);
return obj;
}
DevHandle HdmiOpen(uint16_t busNum)
{
DevHandle *obj = (DevHandle *)HdmiCntlrObjGet(busNum);
int32_t ret;
if (obj == NULL) {
return NULL;
}
#ifdef __USER__
struct HdfIoService *service = (struct HdfIoService *)obj;
if (service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
HDF_LOGE("HdmiOpen: dispatcher or Dispatch is NULL!");
return NULL;
}
ret = service->dispatcher->Dispatch(&service->object, HDMI_CMD_OPEN, NULL, NULL);
if (ret != HDF_SUCCESS) {
HDF_LOGE("HdmiOpen: failed to send service call:%d", ret);
return NULL;
}
#else
ret = HdmiCntlrOpen((struct HdmiCntlr *)obj);
if (ret != HDF_SUCCESS) {
return NULL;
}
#endif
return obj;
}
int32_t HdmiStart(DevHandle handle)
{
#ifdef __USER__
return HdmiUserStart(handle);
#else
return HdmiCntlrStart((struct HdmiCntlr *)handle);
#endif
}
int32_t HdmiStop(DevHandle handle)
{
#ifdef __USER__
return HdmiUserStop(handle);
#else
return HdmiCntlrStop((struct HdmiCntlr *)handle);
#endif
}
int32_t HdmiAvmuteSet(DevHandle handle, bool enable)
{
#ifdef __USER__
return HdmiUserAvmuteSet(handle, enable);
#else
HdmiCntlrAvmuteSet((struct HdmiCntlr *)handle, enable);
return HDF_SUCCESS;
#endif
}
int32_t HdmiDeepColorSet(DevHandle handle, enum HdmiDeepColor color)
{
#ifdef __USER__
return HdmiUserDeepColorSet(handle, color);
#else
return HdmiCntlrDeepColorSet((struct HdmiCntlr *)handle, color);
#endif
}
int32_t HdmiDeepColorGet(DevHandle handle, enum HdmiDeepColor *color)
{
#ifdef __USER__
return HdmiUserDeepColorGet(handle, color);
#else
return HdmiCntlrDeepColorGet((struct HdmiCntlr *)handle, color);
#endif
}
int32_t HdmiSetVideoAttribute(DevHandle handle, struct HdmiVideoAttr *attr)
{
#ifdef __USER__
return HdmiUserSetVideoAttribute(handle, attr);
#else
return HdmiCntlrSetVideoAttribute((struct HdmiCntlr *)handle, attr);
#endif
}
int32_t HdmiSetAudioAttribute(DevHandle handle, struct HdmiAudioAttr *attr)
{
#ifdef __USER__
return HdmiUserSetAudioAttribute(handle, attr);
#else
return HdmiCntlrSetAudioAttribute((struct HdmiCntlr *)handle, attr);
#endif
}
int32_t HdmiSetHdrAttribute(DevHandle handle, struct HdmiHdrAttr *attr)
{
#ifdef __USER__
return HdmiUserSetHdrAttribute(handle, attr);
#else
return HdmiCntlrSetHdrAttribute((struct HdmiCntlr *)handle, attr);
#endif
}
int32_t HdmiReadSinkEdid(DevHandle handle, uint8_t *buffer, uint32_t len)
{
#ifdef __USER__
return HdmiUserGetSinkEdid(handle, buffer, len);
#else
return HdmiCntlrGetSinkEdid((struct HdmiCntlr *)handle, buffer, len);
#endif
}
void HdmiClose(DevHandle handle)
{
#ifdef __USER__
HdmiUserClose(handle);
#else
HdmiCntlrClose((struct HdmiCntlr *)handle);
#endif
}
+806
View File
@@ -0,0 +1,806 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "hdf_log.h"
#include "hdmi_core.h"
#include "securec.h"
#define HDF_LOG_TAG hdmi_infoframe_c
#define HDMI_IEEE_OUI_1_4_1ST 0x03
#define HDMI_IEEE_OUI_1_4_2ND 0x0C
#define HDMI_IEEE_OUI_1_4_3RD 0x00
static void HdmiInfoframeFillCheckSum(uint8_t *data, uint32_t len)
{
uint32_t i;
uint8_t checkSum = 0;
for (i = 0; i < len; i++) {
checkSum += data[i];
}
if (checkSum > 0) {
/*
* The checksum shall be calculated such that a byte-wide sum of all three bytes of the Packet Header and
* all valid bytes of the InfoFrame Packet contents(determined by InfoFrame_length), plus the checksum itself,
* equals zero.
*/
data[3] = HDMI_INFOFRAME_CHECKSUM - checkSum;
}
}
static void HdmiInfoframeFillHeader(struct HdmiInfoframeHeader *header, uint8_t *data, uint32_t len)
{
if (len < HDMI_INFOFRAME_PACKET_HEADER_LEN) {
HDF_LOGE("len = %d, val is too small.", len);
return;
}
data[0] = header->type;
data[1] = header->verNum;
data[2] = header->len;
}
static int32_t HdmiInfoframePacketVsEncoding(union HdmiInfoframeInfo *infoframe, uint8_t *data, uint32_t len)
{
uint32_t lenght;
struct HdmiVs14VsifContent *vsifContent = NULL;
struct HdmiVsUserVsifContent *userContent = NULL;
struct HdmiVsInfoframe *vs = &(infoframe->vs);
lenght = HDMI_INFOFRAME_PACKET_HEADER_LEN + vs->len;
if (len < lenght) {
HDF_LOGE("len = %d, val is too small.", len);
return HDF_ERR_INVALID_PARAM;
}
if (memset_s(data, len, 0, len) != EOK) {
HDF_LOGE("memset_s fail.");
return HDF_ERR_IO;
}
HdmiInfoframeFillHeader(&(infoframe->header), data, len);
if (vs->vsifContent._14Vsif.oui == HDMI_IEEE_OUI_1_4) {
data[4] = HDMI_IEEE_OUI_1_4_1ST;
data[5] = HDMI_IEEE_OUI_1_4_2ND;
data[6] = HDMI_IEEE_OUI_1_4_3RD;
vsifContent = &(vs->vsifContent._14Vsif);
userContent = &(vs->vsifContent.userVsif);
data[7] = (vsifContent->format & HDMI_VENDOR_1_4_FORMAT_MARK) << HDMI_VENDOR_1_4_FORMAT_SHIFT;
if (vsifContent->format == HDMI_VS_VIDEO_FORMAT_4K) {
data[8] = vsifContent->vic;
return HDF_SUCCESS;
} else if (vsifContent->format == HDMI_VS_VIDEO_FORMAT_3D) {
data[8] = (vsifContent->_3dStruct & HDMI_VENDOR_3D_STRUCTURE_MARK) << HDMI_VENDOR_3D_STRUCTURE_SHIFT;
}
data[9] = (vsifContent->_3dExtData & HDMI_VENDOR_3D_EXT_DATA_MARK) << HDMI_VENDOR_3D_EXT_DATA_SHIFT;
if (vsifContent->_3dMetaPresent == false) {
if (userContent->len == 0 || (userContent->len + lenght) > len) {
return HDF_SUCCESS;
}
if (memcpy_s(&data[lenght], (len - lenght), userContent->data, userContent->len) != EOK) {
HDF_LOGE("memcpy_s fail.");
return HDF_ERR_IO;
}
lenght += userContent->len;
}
}
HdmiInfoframeFillCheckSum(data, lenght);
return HDF_SUCCESS;
}
static int32_t HdmiInfoframePacketAviEncoding(union HdmiInfoframeInfo *infoframe, uint8_t *data, uint32_t len)
{
uint32_t lenght;
uint8_t *buff = data;
struct HdmiAviInfoframe *avi = &(infoframe->avi);
lenght = HDMI_INFOFRAME_PACKET_HEADER_LEN + avi->len;
if (len < lenght) {
HDF_LOGE("len = %d, val is too small.", len);
return HDF_ERR_INVALID_PARAM;
}
if (memset_s(buff, len, 0, len) != EOK) {
HDF_LOGE("memset_s fail.");
return HDF_ERR_IO;
}
HdmiInfoframeFillHeader(&(infoframe->header), data, len);
buff += HDMI_INFOFRAME_PACKET_HEADER_LEN;
/* PB1 */
buff[0] |= (avi->colorSpace & HDMI_AVI_COLOR_SPACE_MARK) << HDMI_AVI_COLOR_SPACE_SHIFT;
buff[0] |= (avi->scanMode & HDMI_AVI_SCAN_MODE_MARK);
if (avi->activeFormatInformationPresent == true) {
buff[0] |= (1 << HDMI_AVI_ACTIVE_INFORMATION_SHIFT);
}
if (avi->horizBarInfoPresent == true) {
buff[0] |= (1 << HDMI_AVI_HORIZONTAL_BAR_SHIFT);
}
if (avi->vertBarInfoPresent == true) {
buff[0] |= (1 << HDMI_AVI_VERTICAL_BAR_SHIFT);
}
/* PB2 */
buff[1] |= (avi->colorimetry & HDMI_AVI_COLORIMETRY_MARK) << HDMI_AVI_COLORIMETRY_SHIFT;
buff[1] |= (avi->pictureAspect & HDMI_AVI_PICTURE_ASPECT_RATE_MARK) << HDMI_AVI_PICTURE_ASPECT_RATE_SHIFT;
buff[1] |= (avi->activeAspect & HDMI_AVI_ACTIVE_FORMAT_ASPECT_RATE_MARK);
/* PB3 */
buff[2] |= (avi->extColorimetry & HDMI_AVI_EXT_COLORIMETRY_MARK) << HDMI_AVI_EXT_COLORIMETRY_SHIFT;
buff[2] |= (avi->range & HDMI_AVI_EXT_QUANTIZATION_RANGE_MARK) << HDMI_AVI_EXT_QUANTIZATION_RANGE_SHIFT;
buff[2] |= (avi->nups & HDMI_AVI_NUPS_RANGE_MARK);
if (avi->itc == true) {
buff[2] |= (1 << HDMI_AVI_IT_CONTENT_SHIFT);
}
/* PB4 */
buff[3] = avi->vic;
/* PB5 */
buff[4] |= (avi->yccRange & HDMI_AVI_YCC_QUANTIZATION_RANGE_MARK) << HDMI_AVI_YCC_QUANTIZATION_RANGE_SHIFT;
buff[4] |= (avi->itcType & HDMI_AVI_IT_CONTENT_TYPE_MARK) << HDMI_AVI_IT_CONTENT_TYPE_SHIFT;
buff[4] |= (avi->pixelRepetitionFactor & HDMI_AVI_PIXEL_REPETION_FACTOR_MARK);
/* PB6 */
buff[5] = (uint8_t)(avi->topBar & HDMI_AVI_BAR_MODE_MARK);
/* PB7 */
buff[6] = (uint8_t)((avi->topBar >> HDMI_AVI_BAR_MODE_SHIFT) & HDMI_AVI_BAR_MODE_MARK);
/* PB8 */
buff[7] = (uint8_t)(avi->bottomBar & HDMI_AVI_BAR_MODE_MARK);
/* PB9 */
buff[8] = (uint8_t)((avi->bottomBar >> HDMI_AVI_BAR_MODE_SHIFT) & HDMI_AVI_BAR_MODE_MARK);
/* PB10 */
buff[9] = (uint8_t)(avi->leftBar & HDMI_AVI_BAR_MODE_MARK);
/* PB11 */
buff[10] = (uint8_t)((avi->leftBar >> HDMI_AVI_BAR_MODE_SHIFT) & HDMI_AVI_BAR_MODE_MARK);
/* PB12 */
buff[11] = (uint8_t)(avi->rightBar & HDMI_AVI_BAR_MODE_MARK);
/* PB13 */
buff[12] = (uint8_t)((avi->rightBar >> HDMI_AVI_BAR_MODE_SHIFT) & HDMI_AVI_BAR_MODE_MARK);
HdmiInfoframeFillCheckSum(data, lenght);
return HDF_SUCCESS;
}
static int32_t HdmiInfoframePacketSpdEncoding(union HdmiInfoframeInfo *infoframe, uint8_t *data, uint32_t len)
{
uint32_t lenght;
uint8_t *buff = data;
struct HdmiSpdInfoframe *spd = &(infoframe->spd);
lenght = HDMI_INFOFRAME_PACKET_HEADER_LEN + spd->len;
if (len < lenght) {
HDF_LOGE("len = %d, val is too small.", len);
return HDF_ERR_INVALID_PARAM;
}
if (memset_s(buff, len, 0, len) != EOK) {
HDF_LOGE("memset_s fail.");
return HDF_ERR_IO;
}
buff += HDMI_INFOFRAME_PACKET_HEADER_LEN;
/* PB1~PB8 */
if (memcpy_s(buff, (len - HDMI_INFOFRAME_PACKET_HEADER_LEN), spd->vendorName, sizeof(spd->vendorName)) != EOK) {
HDF_LOGE("memcpy_s fail.");
return HDF_ERR_IO;
}
buff += HDMI_SPD_VENDOR_NAME_LEN;
/* PB9~PB24 */
if (memcpy_s(buff, (len - HDMI_INFOFRAME_PACKET_HEADER_LEN - HDMI_SPD_VENDOR_NAME_LEN),
spd->productDescription, sizeof(spd->productDescription)) != EOK) {
HDF_LOGE("memcpy_s fail.");
return HDF_ERR_IO;
}
buff += HDMI_SPD_PRODUCT_DESCRIPTION_LEN;
/* PB25 */
buff[0] = spd->sdi;
HdmiInfoframeFillCheckSum(data, lenght);
return HDF_SUCCESS;
}
static int32_t HdmiInfoframePacketAudioEncoding(union HdmiInfoframeInfo *infoframe, uint8_t *data, uint32_t len)
{
uint32_t lenght;
uint8_t *buff = data;
struct HdmiAudioInfoframe *audio = &(infoframe->audio);
lenght = HDMI_INFOFRAME_PACKET_HEADER_LEN + audio->len;
if (len < lenght) {
HDF_LOGE("len = %d, val is too small.", len);
return HDF_ERR_INVALID_PARAM;
}
if (memset_s(buff, len, 0, len) != EOK) {
HDF_LOGE("memset_s fail.");
return HDF_ERR_IO;
}
HdmiInfoframeFillHeader(&(infoframe->header), data, len);
buff += HDMI_INFOFRAME_PACKET_HEADER_LEN;
/* PB1 */
buff[0] |= (audio->codingType & HDMI_AUDIO_CODING_TYPE_MARK) << HDMI_AUDIO_CODING_TYPE_SHIFT;
buff[0] |= (audio->channelCount & HDMI_AUDIO_CHANNEL_COUNT_MARK);
/* PB2 */
buff[1] |= (audio->sampleFreq & HDMI_AUDIO_SAMPLE_FREQUENCY_MARK) << HDMI_AUDIO_SAMPLE_FREQUENCY_SHIFT;
buff[1] |= (audio->sampleSize & HDMI_AUDIO_SAMPLE_SIZE_MARK);
/* PB3 */
buff[2] |= (audio->codingExtType & HDMI_AUDIO_CXT_MARK);
/* PB4 */
buff[3] |= audio->channelAllocation;
/* PB5 */
buff[4] |= (audio->levelShiftValue & HDMI_AUDIO_LEVEL_SHIFT_VALUE_MARK) << HDMI_AUDIO_LEVEL_SHIFT_VALUE_SHIFT;
buff[4] |= (audio->playBackLevel & HDMI_AUDIO_LEF_PLAYBACK_LEVEL_MARK);
if (audio->dmInh == true) {
buff[4] |= (1 << HDMI_AUDIO_DM_INH_SHIFT);
}
HdmiInfoframeFillCheckSum(data, lenght);
return HDF_SUCCESS;
}
static int32_t HdmiInfoframePacketDrmEncoding(union HdmiInfoframeInfo *infoframe, uint8_t *data, uint32_t len)
{
uint32_t lenght;
uint8_t *buff = data;
struct HdmiDrmInfoframe *drm = &(infoframe->drm);
struct HdmiStaticMetadataDescriptor1st *des = &(drm->des.type1);
lenght = HDMI_INFOFRAME_PACKET_HEADER_LEN + drm->len;
if (len < lenght) {
HDF_LOGE("len = %d, val is too small.", len);
return HDF_ERR_INVALID_PARAM;
}
if (memset_s(buff, len, 0, len) != EOK) {
HDF_LOGE("memset_s fail.");
return HDF_ERR_IO;
}
HdmiInfoframeFillHeader(&(infoframe->header), data, len);
buff += HDMI_INFOFRAME_PACKET_HEADER_LEN;
/* PB1 */
buff[0] = drm->eotfType;
/* PB2 */
buff[1] = drm->metadataType;
/* PB3 */
buff[2] = (uint8_t)(des->displayPrimaries0X & HDMI_DRM_METADATA_MARK);
/* PB4 */
buff[3] = (uint8_t)((des->displayPrimaries0X >> HDMI_DRM_METADATA_SHIFT) & HDMI_DRM_METADATA_MARK);
/* PB5 */
buff[4] = (uint8_t)(des->displayPrimaries0Y & HDMI_DRM_METADATA_MARK);
/* PB6 */
buff[5] = (uint8_t)((des->displayPrimaries0Y & HDMI_DRM_METADATA_MARK) & HDMI_DRM_METADATA_MARK);
/* PB7 */
buff[6] = (uint8_t)(des->displayPrimaries1X & HDMI_DRM_METADATA_MARK);
/* PB8 */
buff[7] = (uint8_t)((des->displayPrimaries1X & HDMI_DRM_METADATA_MARK) & HDMI_DRM_METADATA_MARK);
/* PB9 */
buff[8] = (uint8_t)(des->displayPrimaries1Y & HDMI_DRM_METADATA_MARK);
/* PB10 */
buff[9] = (uint8_t)((des->displayPrimaries1Y & HDMI_DRM_METADATA_MARK) & HDMI_DRM_METADATA_MARK);
/* PB11 */
buff[10] = (uint8_t)(des->displayPrimaries2X & HDMI_DRM_METADATA_MARK);
/* PB12 */
buff[11] = (uint8_t)((des->displayPrimaries2X & HDMI_DRM_METADATA_MARK) & HDMI_DRM_METADATA_MARK);
/* PB13 */
buff[12] = (uint8_t)(des->displayPrimaries2Y & HDMI_DRM_METADATA_MARK);
/* PB14 */
buff[13] = (uint8_t)((des->displayPrimaries2Y & HDMI_DRM_METADATA_MARK) & HDMI_DRM_METADATA_MARK);
/* PB15 */
buff[14] = (uint8_t)(des->whitePointX & HDMI_DRM_METADATA_MARK);
/* PB16 */
buff[15] = (uint8_t)((des->whitePointX & HDMI_DRM_METADATA_MARK) & HDMI_DRM_METADATA_MARK);
/* PB17 */
buff[16] = (uint8_t)(des->whitePointY & HDMI_DRM_METADATA_MARK);
/* PB18 */
buff[17] = (uint8_t)((des->whitePointY & HDMI_DRM_METADATA_MARK) & HDMI_DRM_METADATA_MARK);
/* PB19 */
buff[18] = (uint8_t)(des->maxDisplayMasteringLuminance & HDMI_DRM_METADATA_MARK);
/* PB20 */
buff[19] = (uint8_t)((des->maxDisplayMasteringLuminance & HDMI_DRM_METADATA_MARK) & HDMI_DRM_METADATA_MARK);
/* PB21 */
buff[20] = (uint8_t)(des->minDisplayMasteringLuminance & HDMI_DRM_METADATA_MARK);
/* PB22 */
buff[21] = (uint8_t)((des->minDisplayMasteringLuminance & HDMI_DRM_METADATA_MARK) & HDMI_DRM_METADATA_MARK);
/* PB23 */
buff[22] = (uint8_t)(des->maxContentLightLevel & HDMI_DRM_METADATA_MARK);
/* PB24 */
buff[23] = (uint8_t)((des->maxContentLightLevel & HDMI_DRM_METADATA_MARK) & HDMI_DRM_METADATA_MARK);
/* PB25 */
buff[24] = (uint8_t)(des->maxFrameAverageLightLevel & HDMI_DRM_METADATA_MARK);
/* PB26 */
buff[25] = (uint8_t)((des->maxFrameAverageLightLevel & HDMI_DRM_METADATA_MARK) & HDMI_DRM_METADATA_MARK);
HdmiInfoframeFillCheckSum(data, lenght);
return HDF_SUCCESS;
}
static int32_t HdmiInfoframePacketEncoding(union HdmiInfoframeInfo *infoframe,
enum HdmiPacketType type, uint8_t *data, uint32_t len)
{
int32_t ret;
if (infoframe == NULL || data == NULL) {
HDF_LOGE("input param is invalid.");
return HDF_ERR_INVALID_PARAM;
}
switch (type) {
case HDMI_INFOFRAME_PACKET_TYPE_VS:
ret = HdmiInfoframePacketVsEncoding(infoframe, data, len);
break;
case HDMI_INFOFRAME_PACKET_TYPE_AVI:
ret = HdmiInfoframePacketAviEncoding(infoframe, data, len);
break;
case HDMI_INFOFRAME_PACKET_TYPE_SPD:
ret = HdmiInfoframePacketSpdEncoding(infoframe, data, len);
break;
case HDMI_INFOFRAME_PACKET_TYPE_AUDIO:
ret = HdmiInfoframePacketAudioEncoding(infoframe, data, len);
break;
case HDMI_INFOFRAME_PACKET_TYPE_DRM:
ret = HdmiInfoframePacketDrmEncoding(infoframe, data, len);
break;
default:
HDF_LOGD("type %d not support.", type);
ret = HDF_ERR_NOT_SUPPORT;
}
return ret;
}
static int32_t HdmiInfoframeSend(struct HdmiInfoframe *frame, union HdmiInfoframeInfo *infoframe)
{
uint8_t buffer[HDMI_INFOFRAME_LEN] = {0};
struct HdmiCntlr *cntlr = NULL;
int32_t ret;
if (frame == NULL || frame->priv == NULL || infoframe == NULL) {
HDF_LOGE("HdmiInfoframeSend: input param is invalid.");
return HDF_ERR_INVALID_PARAM;
}
cntlr = (struct HdmiCntlr *)frame->priv;
if (cntlr->ops == NULL || cntlr->ops->infoframeSend == NULL || cntlr->ops->infoframeEnable == NULL) {
HDF_LOGD("HdmiInfoframeSend not support.");
return HDF_ERR_NOT_SUPPORT;
}
ret = HdmiInfoframePacketEncoding(infoframe, infoframe->header.type, buffer, HDMI_INFOFRAME_LEN);
if (ret != HDF_SUCCESS) {
HDF_LOGE("encding infoframe %d fail", infoframe->header.type);
return ret;
}
HdmiCntlrLock(cntlr);
cntlr->ops->infoframeEnable(cntlr, infoframe->header.type, false);
ret = cntlr->ops->infoframeSend(cntlr, infoframe->header.type, buffer, HDMI_INFOFRAME_LEN);
if (ret != HDF_SUCCESS) {
HDF_LOGE("send infoframe %d fail", infoframe->header.type);
HdmiCntlrUnlock(cntlr);
return ret;
}
cntlr->ops->infoframeEnable(cntlr, infoframe->header.type, true);
HdmiCntlrUnlock(cntlr);
return HDF_SUCCESS;
}
static void HdmiFillAviHdrInfoframe(struct HdmiAviInfoframe *avi,
struct HdmiVideoAttr *videoAttr, struct HdmiHdrAttr *HdrAttr, struct HdmiCommonAttr *commAttr)
{
switch (HdrAttr->mode) {
case HDMI_HDR_MODE_CEA_861_3:
case HDMI_HDR_MODE_CEA_861_3_AUTHEN:
avi->colorimetry = videoAttr->colorimetry;
avi->extColorimetry = videoAttr->extColorimetry;
avi->colorSpace = commAttr->colorSpace;
if (HdrAttr->mode == HDMI_HDR_MODE_CEA_861_3_AUTHEN) {
avi->colorSpace = HDMI_COLOR_SPACE_YCBCR422;
}
avi->range = videoAttr->quantization;
avi->yccRange = videoAttr->yccQuantization;
break;
case HDMI_HDR_MODE_DOLBY_NORMAL:
avi->colorSpace = HDMI_COLOR_SPACE_YCBCR422;
avi->colorimetry = (videoAttr->xvycc == true) ? HDMI_COLORIMETRY_EXTENDED : videoAttr->colorimetry;
avi->extColorimetry = videoAttr->extColorimetry;
avi->range = videoAttr->quantization;
avi->yccRange = HDMI_YCC_QUANTIZATION_RANGE_FULL;
break;
case HDMI_HDR_MODE_DOLBY_TUNNELING:
avi->colorSpace = HDMI_COLOR_SPACE_RGB;
avi->colorimetry = (videoAttr->xvycc == true) ? HDMI_COLORIMETRY_EXTENDED : videoAttr->colorimetry;
avi->extColorimetry = videoAttr->extColorimetry;
avi->range = HDMI_QUANTIZATION_RANGE_FULL;
avi->yccRange = videoAttr->yccQuantization;
break;
default:
avi->colorSpace = commAttr->colorSpace;
avi->colorimetry = (videoAttr->xvycc == true) ? HDMI_COLORIMETRY_EXTENDED : videoAttr->colorimetry;
avi->extColorimetry = videoAttr->extColorimetry;
avi->range = videoAttr->quantization;
avi->yccRange = videoAttr->yccQuantization;
break;
}
}
static void HdmiFillAviInfoframeVersion(struct HdmiAviInfoframe *avi)
{
/*
* see hdmi spec2.0 10.1.
* The Y2 and VIC7 bits are simply set to zero in a Version 2 AVI InfoFrame and might not be decoded by
* some Sinks. A Version 3 AVI InfoFrame shall be used and the Version field set to 0x03 (indicating that
* the Sink shall decode the additional most-significant bits) whenever either of the most-significant bits
* Y2 or VIC7 are set to '1'. If both Y2 and VIC7 are set to '0', then a Version 2 AVI InfoFrame shall be used
* and the Version field shall be set to 0x02 (indicating that the Sink does not have to decode the additional
* most-significant bits).
*/
avi->verNum = HDMI_AVI_VERSION2;
if (((uint32_t)avi->colorSpace & HDMI_AVI_Y2_MASK) > 0 ||
(avi->vic > HDMI_VIC_5120X2160P100_64_27)) {
avi->verNum = HDMI_AVI_VERSION3;
} else if (avi->colorimetry == HDMI_COLORIMETRY_EXTENDED &&
avi->extColorimetry == HDMI_EXTENDED_COLORIMETRY_ADDITIONAL) {
/*
* (C1,C0) is (1,1) and (EC2,EC1,EC0) is (1,1,1), version shall be 4.
* All fields of the Version 4 AVI InfoFrame are the same as Version 3 AVI InfoFrame,
* except for the InfoFrame Version Number, Length of AVI InfoFrame, and additional Data Byte 14.
*/
avi->verNum = HDMI_AVI_VERSION4;
(avi->len)++;
}
}
static void HdmiFillAviInfoframe(struct HdmiAviInfoframe *avi,
struct HdmiVideoAttr *videoAttr, struct HdmiHdrAttr *HdrAttr, struct HdmiCommonAttr *commAttr)
{
bool enable3d;
if (memset_s(avi, sizeof(struct HdmiAviInfoframe), 0, sizeof(struct HdmiAviInfoframe)) != EOK) {
HDF_LOGE("fill vsif, memset_s fail.");
return;
}
avi->type = HDMI_INFOFRAME_PACKET_TYPE_AVI;
avi->len = HDMI_AVI_INFOFRAME_LEN;
avi->activeFormatInformationPresent = true;
avi->colorSpace = commAttr->colorSpace;
avi->activeAspect = videoAttr->activeAspect;
avi->pictureAspect = videoAttr->aspect;
avi->colorimetry = (videoAttr->xvycc == true) ? HDMI_COLORIMETRY_EXTENDED : videoAttr->colorimetry;
avi->nups = videoAttr->nups;
avi->range = videoAttr->quantization;
avi->extColorimetry = videoAttr->extColorimetry;
enable3d = (videoAttr->_3dStruct >= HDMI_VS_VIDEO_3D_BUTT) ? false : true;
avi->vic = HdmiCommonGetVic(videoAttr->timing, videoAttr->aspect, enable3d);
avi->pixelRepetitionFactor = (uint8_t)videoAttr->pixelRepeat;
avi->yccRange = videoAttr->yccQuantization;
HdmiFillAviHdrInfoframe(avi, videoAttr, HdrAttr, commAttr);
HdmiFillAviInfoframeVersion(avi);
}
int32_t HdmiAviInfoframeSend(struct HdmiInfoframe *frame, bool enable)
{
struct HdmiCntlr *cntlr = NULL;
union HdmiInfoframeInfo infoframe = {0};
if (frame == NULL || frame->priv == NULL) {
HDF_LOGE("HdmiAviInfoframeSend: input param is invalid.");
return HDF_ERR_INVALID_PARAM;
}
cntlr = (struct HdmiCntlr *)frame->priv;
if (cntlr->ops == NULL || cntlr->ops->infoframeEnable == NULL || cntlr->ops->infoframeSend == NULL) {
HDF_LOGD("HdmiAviInfoframeSend not support.");
return HDF_ERR_NOT_SUPPORT;
}
if (enable == false) {
cntlr->ops->infoframeEnable(cntlr, HDMI_INFOFRAME_PACKET_TYPE_AVI, false);
return HDF_SUCCESS;
}
HdmiFillAviInfoframe(&(frame->avi), &(cntlr->attr.videoAttr), &(cntlr->attr.hdrAttr), &(cntlr->attr.commAttr));
infoframe.avi = frame->avi;
return HdmiInfoframeSend(frame, &infoframe);
}
void HdmiFillAudioInfoframe(struct HdmiAudioInfoframe *audio, struct HdmiAudioAttr *audioAttr)
{
if (memset_s(audio, sizeof(struct HdmiAudioInfoframe), 0, sizeof(struct HdmiAudioInfoframe)) != EOK) {
HDF_LOGE("fill vsif, memset_s fail.");
return;
}
audio->type = HDMI_INFOFRAME_PACKET_TYPE_AUDIO;
audio->len = HDMI_AUDIO_INFOFRAME_LEN;
audio->verNum = HDMI_AUDIO_INFOFRAME_VERSION;
/* fill channels. */
if (audioAttr->ifType != HDMI_AUDIO_IF_TYPE_I2S) {
HDF_LOGI("audio channel refer to stream.");
} else {
HDF_LOGI("audio channel %u \n", audioAttr->channels);
audio->channelCount = (audioAttr->channels >= 2) ? (audioAttr->channels - 1) : 0;
}
/* fill coding type. */
if (audioAttr->codingType == HDMI_AUDIO_CODING_TYPE_AC3 || audioAttr->codingType == HDMI_AUDIO_CODING_TYPE_DTS ||
audioAttr->codingType == HDMI_AUDIO_CODING_TYPE_EAC3 || audioAttr->codingType == HDMI_AUDIO_CODING_TYPE_DTS_HD) {
audio->codingType = audioAttr->codingType;
} else {
audio->codingType = HDMI_AUDIO_CODING_TYPE_STREAM;
}
/* fill CA field. see CEA-861-D table 20. */
switch (audioAttr->channels) {
case HDMI_AUDIO_FORMAT_CHANNEL_3:
audio->channelAllocation = 0x01; /* 1 channel */
break;
case HDMI_AUDIO_FORMAT_CHANNEL_6:
audio->channelAllocation = 0x0b; /* 3, 4 channel */
break;
case HDMI_AUDIO_FORMAT_CHANNEL_8:
audio->channelAllocation = 0x13; /* 1, 2, 5 channel */
break;
default:
audio->channelAllocation = 0x00; /* 0 channel */
break;
}
}
int32_t HdmiAudioInfoframeSend(struct HdmiInfoframe *frame, bool enable)
{
struct HdmiCntlr *cntlr = NULL;
union HdmiInfoframeInfo infoframe = {0};
if (frame == NULL || frame->priv == NULL) {
HDF_LOGE("HdmiAudioInfoframeSend: input param is invalid.");
return HDF_ERR_INVALID_PARAM;
}
cntlr = (struct HdmiCntlr *)frame->priv;
if (cntlr->ops == NULL || cntlr->ops->infoframeEnable == NULL) {
HDF_LOGD("HdmiAudioInfoframeSend not support.");
return HDF_ERR_NOT_SUPPORT;
}
if (enable == false) {
HdmiCntlrLock(cntlr);
cntlr->ops->infoframeEnable(cntlr, HDMI_INFOFRAME_PACKET_TYPE_AUDIO, false);
HdmiCntlrUnlock(cntlr);
return HDF_SUCCESS;
}
HdmiFillAudioInfoframe(&(frame->audio), &(cntlr->attr.audioAttr));
infoframe.audio = frame->audio;
return HdmiInfoframeSend(frame, &infoframe);
}
static void HdmiFillDrmInfoframe(struct HdmiDrmInfoframe *drm, struct HdmiHdrAttr *HdrAttr)
{
if (memset_s(drm, sizeof(struct HdmiDrmInfoframe), 0, sizeof(struct HdmiDrmInfoframe)) != EOK) {
HDF_LOGE("fill vsif, memset_s fail.");
return;
}
drm->type = HDMI_INFOFRAME_PACKET_TYPE_DRM;
drm->len = HDMI_DRM_INFOFRAME_LEN;
drm->verNum = HDMI_DRM_INFOFRAME_VERSION;
drm->eotfType = HdrAttr->eotfType;
drm->metadataType = HdrAttr->metadataType;
drm->des = HdrAttr->descriptor;
}
int32_t HdmiDrmInfoframeSend(struct HdmiInfoframe *frame, bool enable)
{
struct HdmiCntlr *cntlr = NULL;
union HdmiInfoframeInfo infoframe = {0};
if (frame == NULL || frame->priv == NULL) {
HDF_LOGE("HdmiDrmInfoframeSend: input param is invalid.");
return HDF_ERR_INVALID_PARAM;
}
cntlr = (struct HdmiCntlr *)frame->priv;
if (cntlr->ops == NULL || cntlr->ops->infoframeEnable == NULL) {
HDF_LOGD("HdmiDrmInfoframeSend not support.");
return HDF_ERR_NOT_SUPPORT;
}
if (enable == false) {
cntlr->ops->infoframeEnable(cntlr, HDMI_INFOFRAME_PACKET_TYPE_DRM, false);
return HDF_SUCCESS;
}
HdmiFillDrmInfoframe(&(frame->drm), &(cntlr->attr.hdrAttr));
infoframe.drm = frame->drm;
return HdmiInfoframeSend(frame, &infoframe);
}
static uint8_t HdmiGetVsifLength(struct HdmiVs14VsifContent *_14Vsif, bool dolbyEnable, bool hdrSupport)
{
uint8_t length = 0x07;
if (hdrSupport == true) {
if (dolbyEnable == true) {
length = 0x18;
} else if (_14Vsif->format == HDMI_VS_VIDEO_FORMAT_4K) {
length = 0x05;
} else if (_14Vsif->format == HDMI_VS_VIDEO_FORMAT_3D) {
length = 0x07;
} else {
length = 0x04;
}
}
return length;
}
static void HdmiFill14Vsif(struct HdmiVsInfoframe *vs, struct HdmiVideoAttr *videoAttr)
{
struct HdmiVideo4kInfo *_4kInfo = NULL;
struct HdmiVs14VsifContent *_14Vsif = &(vs->vsifContent._14Vsif);
enum HdmiVic vic;
uint32_t cnt;
_14Vsif->oui = HDMI_IEEE_OUI_1_4;
vic = HdmiCommonGetVic(videoAttr->timing, videoAttr->aspect, false);
if ((vic == HDMI_VIC_3840X2160P24_16_9 || vic == HDMI_VIC_3840X2160P25_16_9 ||
vic == HDMI_VIC_3840X2160P30_16_9 || vic == HDMI_VIC_4096X2160P24_256_135) &&
videoAttr->_3dStruct == HDMI_VS_VIDEO_3D_BUTT) {
_14Vsif->format = HDMI_VS_VIDEO_FORMAT_4K;
for (cnt = 0; cnt <= HDMI_VIDEO_4K_CODES_MAX; cnt++) {
_4kInfo = HdmiCommonGetVideo4kInfo(cnt);
if (_4kInfo != NULL && _4kInfo->timing == videoAttr->timing) {
_14Vsif->vic = _4kInfo->_4kVic;
break;
}
}
} else if (videoAttr->_3dStruct < HDMI_VS_VIDEO_3D_BUTT) { // common 3D
_14Vsif->format = HDMI_VS_VIDEO_FORMAT_3D;
_14Vsif->_3dStruct = videoAttr->_3dStruct;
} else {
_14Vsif->format = HDMI_VS_VIDEO_FORMAT_NULL;
_14Vsif->_3dStruct = videoAttr->_3dStruct;
}
}
static void HdmiFillVsInfoframe(struct HdmiInfoframe *frame, struct HdmiVideoAttr *videoAttr,
bool dolbyEnable, bool hdrSupport)
{
struct HdmiVsInfoframe *vs = &(frame->vs);
int32_t ret;
ret = memset_s(vs, sizeof(struct HdmiVsInfoframe), 0, sizeof(struct HdmiVsInfoframe));
if (ret != EOK) {
HDF_LOGE("fill vsif, memset_s fail.");
return;
}
vs->type = HDMI_INFOFRAME_PACKET_TYPE_VS;
vs->verNum = HDMI_VSIF_VERSION;
HdmiFill14Vsif(vs, videoAttr);
vs->len = HdmiGetVsifLength(&(vs->vsifContent._14Vsif), dolbyEnable, hdrSupport);
/* fill user vendor data */
vs->vsifContent.userVsif.len = frame->userVsif.len;
ret = memcpy_s(vs->vsifContent.userVsif.data, HDMI_VENDOR_USER_DATA_MAX_LEN,
frame->userVsif.data, frame->userVsif.len);
if (ret != EOK) {
HDF_LOGE("fill vsif, memcpy_s fail.");
}
}
int32_t HdmiVsInfoframeSend(struct HdmiInfoframe *frame, bool enable, bool dolbyEnable)
{
struct HdmiCntlr *cntlr = NULL;
union HdmiInfoframeInfo infoframe = {0};
if (frame == NULL || frame->priv == NULL) {
HDF_LOGE("HdmiVsInfoframeSend: input param is invalid.");
return HDF_ERR_INVALID_PARAM;
}
cntlr = (struct HdmiCntlr *)frame->priv;
if (cntlr->ops == NULL || cntlr->ops->infoframeEnable == NULL) {
HDF_LOGD("HdmiVsInfoframeSend not support.");
return HDF_ERR_NOT_SUPPORT;
}
if (enable == false) {
cntlr->ops->infoframeEnable(cntlr, HDMI_INFOFRAME_PACKET_TYPE_VS, false);
return HDF_SUCCESS;
}
HdmiFillVsInfoframe(frame, &(cntlr->attr.videoAttr), dolbyEnable, frame->hdrSupport);
infoframe.vs = frame->vs;
return HdmiInfoframeSend(frame, &infoframe);
}
static void HdmiFillSpdInfoframe(struct HdmiSpdInfoframe *spd, char *vendorName,
char *productName, enum HdmiSpdSdi sdi)
{
uint32_t len, length;
if (memset_s(spd, sizeof(struct HdmiSpdInfoframe), 0, sizeof(struct HdmiSpdInfoframe)) != EOK) {
HDF_LOGE("fill spd infoframe, memset_s fail.");
return;
}
spd->type = HDMI_INFOFRAME_PACKET_TYPE_SPD;
spd->len = HDMI_SPD_INFOFRAME_LEN;
spd->verNum = HDMI_SPD_VERSION;
spd->sdi = sdi;
len = (uint32_t)strlen(vendorName);
length = (uint32_t)sizeof(spd->vendorName);
length = (length > len) ? len : length;
if (memcpy_s(spd->vendorName, length, vendorName, length) != EOK) {
HDF_LOGE("fill spd infoframe vendor name, memcpy_s fail.");
}
len = (uint32_t)strlen(productName);
length = (uint32_t)sizeof(spd->productDescription);
length = (length > len) ? len : length;
if (memcpy_s(spd->productDescription, length, productName, length) != EOK) {
HDF_LOGE("fill spd infoframe product name, memcpy_s fail.");
}
}
int32_t HdmiSpdInfoframeSend(struct HdmiInfoframe *frame, bool enable,
char *vendorName, char *productName, enum HdmiSpdSdi sdi)
{
struct HdmiCntlr *cntlr = NULL;
union HdmiInfoframeInfo infoframe = {0};
if (frame == NULL || frame->priv == NULL) {
HDF_LOGE("HdmiSpdInfoframeSend: input param is invalid.");
return HDF_ERR_INVALID_PARAM;
}
cntlr = (struct HdmiCntlr *)frame->priv;
if (cntlr->ops == NULL || cntlr->ops->infoframeEnable == NULL) {
HDF_LOGD("HdmiSpdInfoframeSend not support.");
return HDF_ERR_NOT_SUPPORT;
}
if (enable == false) {
cntlr->ops->infoframeEnable(cntlr, HDMI_INFOFRAME_PACKET_TYPE_SPD, false);
return HDF_SUCCESS;
}
HdmiFillSpdInfoframe(&(frame->spd), vendorName, productName, sdi);
infoframe.spd = frame->spd;
return HdmiInfoframeSend(frame, &infoframe);
}
int32_t HdmiInfoframeGetInfo(struct HdmiInfoframe *frame, enum HdmiPacketType type,
union HdmiInfoframeInfo *infoframe)
{
if (frame == NULL || infoframe == NULL) {
return HDF_ERR_INVALID_PARAM;
}
switch (type) {
case HDMI_INFOFRAME_PACKET_TYPE_VS :
infoframe->vs = frame->vs;
break;
case HDMI_INFOFRAME_PACKET_TYPE_AVI :
infoframe->avi = frame->avi;
break;
case HDMI_INFOFRAME_PACKET_TYPE_AUDIO :
infoframe->audio = frame->audio;
break;
case HDMI_INFOFRAME_PACKET_TYPE_DRM :
infoframe->drm = frame->drm;
break;
default :
HDF_LOGD("infoframe %d not support get", type);
return HDF_ERR_INVALID_PARAM;
}
return HDF_SUCCESS;
}
int32_t HdmiInfoframeSetInfo(struct HdmiInfoframe *frame, enum HdmiPacketType type,
union HdmiInfoframeInfo *infoframe)
{
if (frame == NULL || infoframe == NULL) {
return HDF_ERR_INVALID_PARAM;
}
switch (type) {
case HDMI_INFOFRAME_PACKET_TYPE_VS :
frame->vs = infoframe->vs;
break;
case HDMI_INFOFRAME_PACKET_TYPE_AVI :
frame->avi = infoframe->avi;
break;
case HDMI_INFOFRAME_PACKET_TYPE_AUDIO :
frame->audio = infoframe->audio;
break;
case HDMI_INFOFRAME_PACKET_TYPE_DRM :
frame->drm = infoframe->drm;
break;
default :
HDF_LOGD("infoframe %d not support set", type);
return HDF_ERR_INVALID_PARAM;
}
return HDF_SUCCESS;
}
+123
View File
@@ -0,0 +1,123 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "hdmi_ncts.h"
#define HDF_LOG_TAG hdmi_ncts_c
#define HDMI_NCTS_INVALID_VALUE 0xffffffff
/*
* see hdmi1.4 table 7-1¡¢7-2¡¢7-3.
* The exact relationship: 128 * fs = tmdsClock * N / CTS.
*/
static struct HdmiAudioNCts g_audioNctsMap[] = {
{ 32000, 25174, 4576, 28125 },
{ 32000, 25200, 4096, 25200 },
{ 32000, 27000, 4096, 27000 },
{ 32000, 27027, 4096, 27027 },
{ 32000, 54000, 4096, 54000 },
{ 32000, 54054, 4096, 54054 },
{ 32000, 74175, 11648, 210937},
{ 32000, 74250, 4096, 74250 },
{ 32000, 148351, 11648, 421875 },
{ 32000, 148500, 4096, 148500 },
{ 32000, 296703, 5824, 421875 },
{ 32000, 297000, 3072, 222750 },
{ 32000, 593406, 5824, 843750 },
{ 32000, 594000, 3072, 445500 },
{ 32000, 0, 4096, 0 },
{ 44100, 25174, 7007, 31250 },
{ 44100, 25200, 6272, 28000 },
{ 44100, 27000, 6272, 30000 },
{ 44100, 27027, 6272, 30030 },
{ 44100, 54000, 6272, 60000 },
{ 44100, 54054, 6272, 60060 },
{ 44100, 74175, 17836, 234375 },
{ 44100, 74250, 6272, 82500 },
{ 44100, 148351, 8918, 234375 },
{ 44100, 148500, 6272, 165000 },
{ 44100, 296703, 4459, 234375 },
{ 44100, 297000, 4704, 247500 },
{ 44100, 593406, 8918, 937500 },
{ 44100, 594000, 9408, 990000 },
{ 44100, 0, 6272, 0 },
{ 48000, 25174, 6864, 28125 },
{ 48000, 25200, 6144, 25200 },
{ 48000, 27000, 6144, 27000 },
{ 48000, 27027, 6144, 27027 },
{ 48000, 54000, 6144, 54000 },
{ 48000, 54054, 6144, 54054 },
{ 48000, 74175, 11648, 140625 },
{ 48000, 74250, 6144, 74250 },
{ 48000, 148351, 5824, 140625 },
{ 48000, 148500, 6144, 148500 },
{ 48000, 296703, 5824, 281250 },
{ 48000, 297000, 5120, 247500 },
{ 48000, 593406, 5824, 562500 },
{ 48000, 594000, 6144, 594000 },
{ 48000, 0, 6144, 0 }
};
uint32_t HdmiGetN(uint32_t sampleRate, uint32_t tmdsClock)
{
uint32_t i;
for (i = 0;i < sizeof(g_audioNctsMap) / sizeof(g_audioNctsMap[0]); i++) {
if (g_audioNctsMap[i].sampleRate == sampleRate &&
g_audioNctsMap[i].tmdsClock == tmdsClock) {
return g_audioNctsMap[i].n;
}
if (g_audioNctsMap[i].sampleRate == sampleRate &&
g_audioNctsMap[i].tmdsClock >= (tmdsClock - HDMI_NCTS_TMDS_DEVIATION) &&
g_audioNctsMap[i].tmdsClock <= (tmdsClock + HDMI_NCTS_TMDS_DEVIATION)) {
return g_audioNctsMap[i].n;
}
if (g_audioNctsMap[i].sampleRate == sampleRate &&
g_audioNctsMap[i].tmdsClock == 0) {
return g_audioNctsMap[i].n;
}
}
return HDMI_NCTS_N_DEFAULT;
}
uint32_t HdmiGetCts(uint32_t sampleRate, uint32_t tmdsClock)
{
uint32_t i;
uint32_t tmpN = HDMI_NCTS_INVALID_VALUE;
uint32_t tmpCts = HDMI_NCTS_INVALID_VALUE;
for (i = 0;i < sizeof(g_audioNctsMap) / sizeof(g_audioNctsMap[0]); i++) {
if (g_audioNctsMap[i].sampleRate == sampleRate &&
g_audioNctsMap[i].tmdsClock == tmdsClock) {
tmpN = g_audioNctsMap[i].n;
tmpCts = g_audioNctsMap[i].cts;
break;
}
if (g_audioNctsMap[i].sampleRate == sampleRate &&
g_audioNctsMap[i].tmdsClock >= (tmdsClock - HDMI_NCTS_TMDS_DEVIATION) &&
g_audioNctsMap[i].tmdsClock <= (tmdsClock + HDMI_NCTS_TMDS_DEVIATION)) {
tmpN = g_audioNctsMap[i].n;
tmpCts = g_audioNctsMap[i].cts;
break;
}
if (g_audioNctsMap[i].sampleRate == sampleRate &&
g_audioNctsMap[i].tmdsClock == 0) {
tmpN = g_audioNctsMap[i].n;
tmpCts = g_audioNctsMap[i].cts;
break;
}
}
if (tmpCts == 0 && sampleRate >= 1000) {
tmpCts = (tmpN / HDMI_NCTS_FACTOR) * tmdsClock * 10 / (sampleRate / 1000);
} else if (tmpCts == HDMI_NCTS_INVALID_VALUE && sampleRate >= 1000) {
tmpCts = (HDMI_NCTS_N_DEFAULT / HDMI_NCTS_FACTOR) * tmdsClock * 10 / (sampleRate / 1000);
}
return tmpCts;
}
+384
View File
@@ -0,0 +1,384 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "hdf_log.h"
#include "hdmi_core.h"
#define HDF_LOG_TAG hdmi_scdc_c
#define HDMI_SCDC_READ_SOURCE_VERSION_TIMES 2
int32_t HdmiScdcRead(struct HdmiScdc *scdc, enum HdmiScdcsOffset offset, uint8_t *buffer, uint32_t len)
{
struct HdmiDdcCfg cfg = {0};
struct HdmiCntlr *cntlr = NULL;
if (scdc == NULL || scdc->priv == NULL) {
return HDF_ERR_INVALID_PARAM;
}
cntlr = (struct HdmiCntlr *)scdc->priv;
cfg.type = HDMI_DDC_DEV_SCDC;
cfg.readFlag = true;
cfg.devAddr = HDMI_DDC_SCDC_DEV_ADDRESS;
cfg.data = buffer;
cfg.dataLen = len;
cfg.offset = offset;
cfg.mode = HDMI_DDC_MODE_READ_MUTIL_NO_ACK;
return HdmiDdcTransfer(&(cntlr->ddc), &cfg);
}
int32_t HdmiScdcWrite(struct HdmiScdc *scdc, enum HdmiScdcsOffset offset, uint8_t *buffer, uint32_t len)
{
struct HdmiDdcCfg cfg = {0};
struct HdmiCntlr *cntlr = NULL;
if (scdc == NULL || scdc->priv == NULL) {
return HDF_ERR_INVALID_PARAM;
}
cntlr = (struct HdmiCntlr *)scdc->priv;
cfg.type = HDMI_DDC_DEV_SCDC;
cfg.readFlag = false;
cfg.devAddr = HDMI_DDC_SCDC_DEV_ADDRESS;
cfg.data = buffer;
cfg.dataLen = len;
cfg.offset = offset;
cfg.mode = HDMI_DDC_MODE_WRITE_MUTIL_ACK;
return HdmiDdcTransfer(&(cntlr->ddc), &cfg);
}
int32_t HdmiScdcReadByte(struct HdmiScdc *scdc, enum HdmiScdcsOffset offset, uint8_t *byte)
{
return HdmiScdcRead(scdc, offset, byte, sizeof(*byte));
}
int32_t HdmiScdcWriteByte(struct HdmiScdc *scdc, enum HdmiScdcsOffset offset, uint8_t *byte)
{
return HdmiScdcWrite(scdc, offset, byte, sizeof(*byte));
}
/* read opt */
int32_t HdmiScdcReadSinkVersion(struct HdmiScdc *scdc, uint8_t *sinkVer)
{
return HdmiScdcReadByte(scdc, HDMI_SCDCS_OFFSET_SINK_VERSION, sinkVer);
}
int32_t HdmiScdcReadSourceVersion(struct HdmiScdc *scdc, uint8_t *srcVer)
{
return HdmiScdcReadByte(scdc, HDMI_SCDCS_OFFSET_SOURCE_VERSION, srcVer);
}
int32_t HdmiScdcReadUpdate0(struct HdmiScdc *scdc, uint8_t *flag)
{
return HdmiScdcReadByte(scdc, HDMI_SCDCS_OFFSET_UPDATE_0, flag);
}
int32_t HdmiScdcReadScramblerStatus(struct HdmiScdc *scdc, uint8_t *status)
{
return HdmiScdcReadByte(scdc, HDMI_SCDCS_OFFSET_SCRAMBLER_STATUS, status);
}
int32_t HdmiScdcReadTmdsConfig(struct HdmiScdc *scdc, uint8_t *tmdsCfg)
{
return HdmiScdcReadByte(scdc, HDMI_SCDCS_OFFSET_TMDS_CONFIG, tmdsCfg);
}
int32_t HdmiScdcReadConfig0(struct HdmiScdc *scdc, uint8_t *cfg)
{
return HdmiScdcReadByte(scdc, HDMI_SCDCS_OFFSET_CONFIG_0, cfg);
}
int32_t HdmiScdcReadConfig1(struct HdmiScdc *scdc, uint8_t *cfg)
{
return HdmiScdcReadByte(scdc, HDMI_SCDCS_OFFSET_CONFIG_1, cfg);
}
int32_t HdmiScdcReadTestConfig0(struct HdmiScdc *scdc, uint8_t *testCfg)
{
return HdmiScdcReadByte(scdc, HDMI_SCDCS_OFFSET_TEST_CONFIG_0, testCfg);
}
int32_t HdmiScdcReadTestConfig1(struct HdmiScdc *scdc, uint8_t *testCfg)
{
return HdmiScdcReadByte(scdc, HDMI_SCDCS_OFFSET_TEST_CONFIG_1, testCfg);
}
int32_t HdmiScdcReadStatusFlag0(struct HdmiScdc *scdc, uint8_t *flag)
{
return HdmiScdcReadByte(scdc, HDMI_SCDCS_OFFSET_STASTUS_FLAG_0, flag);
}
int32_t HdmiScdcReadStatusFlag1(struct HdmiScdc *scdc, uint8_t *flag)
{
return HdmiScdcReadByte(scdc, HDMI_SCDCS_OFFSET_STASTUS_FLAG_1, flag);
}
int32_t HdmiScdcReadStatusFlag2(struct HdmiScdc *scdc, uint8_t *flag)
{
return HdmiScdcReadByte(scdc, HDMI_SCDCS_OFFSET_STASTUS_FLAG_2, flag);
}
/* write opt */
int32_t HdmiScdcWriteSourceVersion(struct HdmiScdc *scdc, uint8_t *srcVer)
{
return HdmiScdcWriteByte(scdc, HDMI_SCDCS_OFFSET_SOURCE_VERSION, srcVer);
}
int32_t HdmiScdcWriteUpdate0(struct HdmiScdc *scdc, uint8_t *flag)
{
return HdmiScdcWriteByte(scdc, HDMI_SCDCS_OFFSET_UPDATE_0, flag);
}
int32_t HdmiScdcWriteTmdsConfig(struct HdmiScdc *scdc, uint8_t *tmdsCfg)
{
return HdmiScdcWriteByte(scdc, HDMI_SCDCS_OFFSET_TMDS_CONFIG, tmdsCfg);
}
int32_t HdmiScdcWriteConfig0(struct HdmiScdc *scdc, uint8_t *cfg)
{
return HdmiScdcWriteByte(scdc, HDMI_SCDCS_OFFSET_CONFIG_0, cfg);
}
int32_t HdmiScdcWriteConfig1(struct HdmiScdc *scdc, uint8_t *cfg)
{
return HdmiScdcWriteByte(scdc, HDMI_SCDCS_OFFSET_CONFIG_1, cfg);
}
int32_t HdmiScdcWriteTestConfig0(struct HdmiScdc *scdc, uint8_t *testCfg)
{
return HdmiScdcWriteByte(scdc, HDMI_SCDCS_OFFSET_TEST_CONFIG_0, testCfg);
}
/* cntlr ops */
bool HdmiCntlrScdcSourceScrambleGet(struct HdmiCntlr *cntlr)
{
bool ret;
if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->scdcSourceScrambleGet == NULL) {
return HDF_ERR_INVALID_OBJECT;
}
HdmiCntlrLock(cntlr);
ret = cntlr->ops->scdcSourceScrambleGet(cntlr);
HdmiCntlrUnlock(cntlr);
return ret;
}
int32_t HdmiCntlrScdcSourceScrambleSet(struct HdmiCntlr *cntlr, bool enable)
{
int32_t ret;
if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->scdcSourceScrambleSet == NULL) {
return HDF_ERR_INVALID_OBJECT;
}
HdmiCntlrLock(cntlr);
ret = cntlr->ops->scdcSourceScrambleSet(cntlr, enable);
HdmiCntlrUnlock(cntlr);
return ret;
}
/* scdc opt */
int32_t HdmiScdcRrDisable(struct HdmiScdc *scdc)
{
union HdmiScdcsConfig0 cfg = {0};
union HdmiScdcsTestConfig0 testCfg = {0};
int32_t ret;
if (scdc == NULL) {
return HDF_ERR_INVALID_PARAM;
}
ret = HdmiScdcWriteConfig0(scdc, &(cfg.data));
if (ret != HDF_SUCCESS) {
HDF_LOGE("scdc write config0 fail");
return ret;
}
scdc->status.cfg0 = cfg;
ret = HdmiScdcWriteTestConfig0(scdc, &(testCfg.data));
if (ret != HDF_SUCCESS) {
HDF_LOGE("scdc write test config0 fail");
return ret;
}
scdc->status.testCfg0 = testCfg;
return HDF_SUCCESS;
}
int32_t HdmiScdcScrambleSet(struct HdmiScdc *scdc, struct HdmiScdcScrambleCap *scramble)
{
union HdmiScdcsTmdsConfig cfg = {0};
int32_t ret;
if (scdc == NULL) {
return HDF_ERR_INVALID_PARAM;
}
ret = HdmiCntlrScdcSourceScrambleSet((struct HdmiCntlr *)scdc->priv, scramble->sourceScramble);
if (ret != HDF_SUCCESS) {
HDF_LOGE("scdc source scrambler set fail");
return ret;
}
if (scramble->sinkScramble == true) {
cfg.bits.scramblingEnable = 1;
}
if (scramble->tmdsBitClockRatio40 == true) {
cfg.bits.tmdsBitClockRatio = 1;
}
ret = HdmiScdcWriteTmdsConfig(scdc, &(cfg.data));
if (ret != HDF_SUCCESS) {
HDF_LOGE("scdc write tmds config fail");
return ret;
}
return HDF_SUCCESS;
}
int32_t HdmiScdcScrambleGet(struct HdmiScdc *scdc, struct HdmiScdcScrambleCap *scramble)
{
union HdmiScdcsScramblerStatus status = {0};
union HdmiScdcsTmdsConfig cfg = {0};
int32_t ret;
if (scdc == NULL) {
return HDF_ERR_INVALID_PARAM;
}
ret = HdmiScdcReadScramblerStatus(scdc, &(status.data));
if (ret != HDF_SUCCESS) {
HDF_LOGE("scdc read scrambler status fail");
return ret;
}
scramble->sinkScramble = (status.bits.scramblingStatus ? true : false);
ret = HdmiScdcReadTmdsConfig(scdc, &(cfg.data));
if (ret != HDF_SUCCESS) {
HDF_LOGE("scdc read tmds config fail");
return ret;
}
scramble->tmdsBitClockRatio40 = (cfg.bits.tmdsBitClockRatio ? true : false);
scramble->sourceScramble = HdmiCntlrScdcSourceScrambleGet(scdc->priv);
scdc->status.tmdsCfg = cfg;
scdc->status.scramblerStatus = status;
return HDF_SUCCESS;
}
bool HdmiScdcSinkSupport(struct HdmiScdc *scdc)
{
uint8_t srcVer, i;
int32_t ret;
if (scdc == NULL) {
return HDF_ERR_INVALID_PARAM;
}
for (i = 0; i < HDMI_SCDC_READ_SOURCE_VERSION_TIMES; i++) {
srcVer = HDMI_SCDC_HDMI20_VERSION;
ret = HdmiScdcWriteSourceVersion(scdc, &srcVer);
if (ret != HDF_SUCCESS) {
HDF_LOGE("scdc write source version fail");
return false;
}
ret = HdmiScdcReadSourceVersion(scdc, &srcVer);
if (ret != HDF_SUCCESS) {
HDF_LOGE("scdc read source version fail");
return false;
}
}
scdc->status.sourceVersion = HDMI_SCDC_HDMI20_VERSION;
return true;
}
int32_t HdmiScdcOptMsgHandle(struct HdmiScdc *scdc, enum HdmiScdcOptMsg msg, uint8_t *buffer, uint32_t len)
{
int32_t ret;
if (scdc == NULL || buffer == NULL || len == 0) {
return HDF_ERR_INVALID_PARAM;
}
switch (msg) {
case HDMI_SCDC_OPT_SET_SOURCE_VER :
ret = HdmiScdcWriteSourceVersion(scdc, buffer);
break;
case HDMI_SCDC_OPT_GET_SOURCE_VER :
ret = HdmiScdcReadSourceVersion(scdc, buffer);
break;
case HDMI_SCDC_OPT_GET_SINK_VER :
ret = HdmiScdcReadSinkVersion(scdc, buffer);
break;
case HDMI_SCDC_OPT_SET_FLT_UPDATE :
case HDMI_SCDC_OPT_SET_FRL_START :
ret = HdmiScdcWriteUpdate0(scdc, buffer);
break;
case HDMI_SCDC_OPT_GET_FLT_UPDATE :
case HDMI_SCDC_OPT_GET_FRL_START :
ret = HdmiScdcReadUpdate0(scdc, buffer);
break;
case HDMI_SCDC_OPT_SET_CONFIG1 :
ret = HdmiScdcWriteConfig1(scdc, buffer);
break;
case HDMI_SCDC_OPT_GET_CONFIG1 :
ret = HdmiScdcReadConfig1(scdc, buffer);
break;
case HDMI_SCDC_OPT_GET_TEST_CONFIG_1 :
ret = HdmiScdcReadTestConfig1(scdc, buffer);
break;
case HDMI_SCDC_OPT_GET_FLT_READY :
ret = HdmiScdcReadStatusFlag0(scdc, buffer);
break;
case HDMI_SCDC_OPT_GET_LTP_REQ :
ret = HdmiScdcRead(scdc, HDMI_SCDCS_OFFSET_STASTUS_FLAG_1, buffer, len);
break;
default :
HDF_LOGE("scdc msg handle, msg %d not support.", msg);
ret = HDF_ERR_NOT_SUPPORT;
break;
}
return ret;
}
int32_t HdmiScdcFillScrambleCap(struct HdmiScdc *scdc, struct HdmiScdcScrambleCap *scramble,
enum HdmiTmdsModeType *tmdsMode)
{
struct HdmiCntlr *cntlr = NULL;
struct HdmiCommonAttr *commAttr = NULL;
struct HdmiVideoAttr *videoAttr = NULL;
if (scdc == NULL || scdc->priv == NULL || scramble == NULL || tmdsMode == NULL) {
HDF_LOGD("scdc fill scramble cap: param is null");
return HDF_ERR_INVALID_PARAM;
}
cntlr = (struct HdmiCntlr *)scdc->priv;
commAttr = &(cntlr->attr.commAttr);
videoAttr = &(cntlr->attr.videoAttr);
if (commAttr->enableHdmi == false) {
/* DVI mode */
*tmdsMode = HDMI_TMDS_MODE_DVI;
scramble->sinkScramble = false;
scramble->sourceScramble = false;
scramble->tmdsBitClockRatio40 = false;
if (videoAttr->tmdsClock > HDMI_HDMI14_MAX_TMDS_RATE) {
HDF_LOGE("tmds clock %u can't support in DVI mode.", videoAttr->tmdsClock);
return HDF_ERR_INVALID_PARAM;
}
} else if (videoAttr->tmdsClock > HDMI_HDMI14_MAX_TMDS_RATE) {
*tmdsMode = HDMI_TMDS_MODE_HDMI_2_0;
scramble->sinkScramble = true;
scramble->sourceScramble = true;
scramble->tmdsBitClockRatio40 = true;
} else {
*tmdsMode = HDMI_TMDS_MODE_HDMI_1_4;
scramble->sinkScramble = false;
scramble->sourceScramble = false;
scramble->tmdsBitClockRatio40 = false;
}
return HDF_SUCCESS;
}