#define EXTENSION_VENDOR_SPECIFIC 0x1
#define EXTENSION_COLORMETRY_TAG 0x5
/* DRM stands for "Dynamic Range and Mastering " */
-#define EXTENSION_DRM_TAG 0x6
+#define EXTENSION_DRM_STATIC_TAG 0x6
+#define EXTENSION_DRM_DYNAMIC_TAG 0x7
+ #define TYPE_1_HDR_METADATA_TYPE 0x0001
+ #define TS_103_433_SPEC_TYPE 0x0002
+ #define ITU_T_H265_SPEC_TYPE 0x0003
+ #define TYPE_4_HDR_METADATA_TYPE 0x0004
/* Video Format Preference Data block */
#define EXTENSION_VFPDB_TAG 0xd
#define EXTENSION_Y420_VDB_TAG 0xe
return -1;
}
-static int Edid_ParsingDRMBlock(struct rx_cap *pRXCap,
+static int Edid_ParsingDRMStaticBlock(struct rx_cap *pRXCap,
unsigned char *buf)
{
unsigned char tag = 0, ext_tag = 0, data_end = 0;
pos++;
ext_tag = buf[pos];
if ((tag != HDMI_EDID_BLOCK_TYPE_EXTENDED_TAG)
- || (ext_tag != EXTENSION_DRM_TAG))
- goto INVALID_DRM;
+ || (ext_tag != EXTENSION_DRM_STATIC_TAG))
+ goto INVALID_DRM_STATIC;
pos++;
pRXCap->hdr_sup_eotf_sdr = !!(buf[pos] & (0x1 << 0));
pRXCap->hdr_sup_eotf_hdr = !!(buf[pos] & (0x1 << 1));
return 0;
}
return 0;
-INVALID_DRM:
- pr_info("[%s] it's not a valid DRM\n", __func__);
+INVALID_DRM_STATIC:
+ pr_info("[%s] it's not a valid DRM STATIC BLOCK\n", __func__);
+ return -1;
+}
+
+static int Edid_ParsingDRMDynamicBlock(struct rx_cap *pRXCap,
+ unsigned char *buf)
+{
+ unsigned char tag = 0, ext_tag = 0, data_end = 0;
+ unsigned int pos = 0;
+ unsigned int type;
+ unsigned int type_length;
+ unsigned int i;
+ unsigned int num;
+
+ tag = (buf[pos] >> 5) & 0x7;
+ data_end = (buf[pos] & 0x1f);
+ pos++;
+ ext_tag = buf[pos];
+ if ((tag != HDMI_EDID_BLOCK_TYPE_EXTENDED_TAG)
+ || (ext_tag != EXTENSION_DRM_DYNAMIC_TAG))
+ goto INVALID_DRM_DYNAMIC;
+ pos++;
+ data_end--;/*extended tag code byte doesn't need*/
+
+ while (data_end) {
+ type_length = buf[pos];
+ pos++;
+ type = (buf[pos + 1] << 8) | buf[pos];
+ pos += 2;
+ switch (type) {
+ case TS_103_433_SPEC_TYPE:
+ num = 1;
+ break;
+ case ITU_T_H265_SPEC_TYPE:
+ num = 2;
+ break;
+ case TYPE_4_HDR_METADATA_TYPE:
+ num = 3;
+ break;
+ case TYPE_1_HDR_METADATA_TYPE:
+ default:
+ num = 0;
+ break;
+ }
+ pRXCap->hdr_dynamic_info[num].hd_len = type_length;
+ pRXCap->hdr_dynamic_info[num].type = type;
+ pRXCap->hdr_dynamic_info[num].support_flags = buf[pos];
+ pos++;
+ for (i = 0; i < type_length - 3; i++) {
+ pRXCap->hdr_dynamic_info[num].optional_fields[i]
+ = buf[pos];
+ pos++;
+ }
+ data_end = data_end - (type_length + 1);
+ }
+
+ return 0;
+INVALID_DRM_DYNAMIC:
+ pr_info("[%s] it's not a valid DRM DYNAMIC BLOCK\n", __func__);
return -1;
}
pRXCap->colorimetry_data =
BlockBuf[offset + 2];
break;
- case EXTENSION_DRM_TAG:
- Edid_ParsingDRMBlock(pRXCap,
+ case EXTENSION_DRM_STATIC_TAG:
+ Edid_ParsingDRMStaticBlock(pRXCap,
&BlockBuf[offset]);
rx_set_hdr_lumi(&BlockBuf[offset],
(BlockBuf[offset] & 0x1f) + 1);
break;
+ case EXTENSION_DRM_DYNAMIC_TAG:
+ Edid_ParsingDRMDynamicBlock(pRXCap,
+ &BlockBuf[offset]);
+ break;
case EXTENSION_VFPDB_TAG:
/* Just record VFPDB offset address, call Edid_ParsingVFPDB() after DTD
* parsing, in case that
} else
dump_dtd_info(t);
}
+static void hdrinfo_to_vinfo(struct vinfo_s *info, struct rx_cap *pRXCap)
+{
+ unsigned int k, l;
+
+ info->hdr_info.hdr_support =
+ (pRXCap->hdr_sup_eotf_sdr << 0) |
+ (pRXCap->hdr_sup_eotf_hdr << 1) |
+ (pRXCap->hdr_sup_eotf_smpte_st_2084 << 2) |
+ (pRXCap->hdr_sup_eotf_hlg << 3);
+ for (l = 0; l < 4; l++) {
+ if (pRXCap->hdr_dynamic_info[l].type == 0) {
+ memset(&info->hdr_info.dynamic_info[l],
+ 0, sizeof(struct hdr_dynamic));
+ continue;
+ }
+ info->hdr_info.dynamic_info[l].type =
+ pRXCap->hdr_dynamic_info[l].type;
+ info->hdr_info.dynamic_info[l].of_len =
+ pRXCap->hdr_dynamic_info[l].hd_len - 3;
+ info->hdr_info.dynamic_info[l].support_flags =
+ pRXCap->hdr_dynamic_info[l].support_flags;
+ for (k = 0; k < (pRXCap->hdr_dynamic_info[l].hd_len - 3); k++) {
+ info->hdr_info.dynamic_info[l].optional_fields[k] =
+ pRXCap->hdr_dynamic_info[l].optional_fields[k];
+ }
+ }
+ info->hdr_info.colorimetry_support =
+ pRXCap->colorimetry_data;
+ info->hdr_info.lumi_max = pRXCap->hdr_lum_max;
+ info->hdr_info.lumi_avg = pRXCap->hdr_lum_avg;
+ info->hdr_info.lumi_min = pRXCap->hdr_lum_min;
+ pr_info(EDID "update rx hdr info %x at edid parsing\n",
+ info->hdr_info.hdr_support);
+}
+
int hdmitx_edid_parse(struct hdmitx_dev *hdmitx_device)
{
if (info) {
if (!((strncmp(info->name, "480cvbs", 7) == 0) ||
(strncmp(info->name, "576cvbs", 7) == 0) ||
- (strncmp(info->name, "null", 4) == 0))) {
- info->hdr_info.hdr_support =
- (pRXCap->hdr_sup_eotf_sdr << 0) |
- (pRXCap->hdr_sup_eotf_hdr << 1) |
- (pRXCap->hdr_sup_eotf_smpte_st_2084 << 2) |
- (pRXCap->hdr_sup_eotf_hlg << 3);
- info->hdr_info.colorimetry_support =
- pRXCap->colorimetry_data;
- info->hdr_info.lumi_max = pRXCap->hdr_lum_max;
- info->hdr_info.lumi_avg = pRXCap->hdr_lum_avg;
- info->hdr_info.lumi_min = pRXCap->hdr_lum_min;
- pr_info(EDID "update rx hdr info %x at edid parsing\n",
- info->hdr_info.hdr_support);
- }
+ (strncmp(info->name, "null", 4) == 0)))
+ hdrinfo_to_vinfo(info, pRXCap);
}
return 0;
}
+static void hdrinfo_to_vinfo(struct vinfo_s *info, struct hdmitx_dev *hdev)
+{
+ unsigned int i, j;
+
+ info->hdr_info.hdr_support = (hdev->RXCap.hdr_sup_eotf_sdr << 0)
+ | (hdev->RXCap.hdr_sup_eotf_hdr << 1)
+ | (hdev->RXCap.hdr_sup_eotf_smpte_st_2084 << 2)
+ | (hdev->RXCap.hdr_sup_eotf_hlg << 3);
+ for (i = 0; i < 4; i++) {
+ if (hdev->RXCap.hdr_dynamic_info[i].type == 0) {
+ memset(&info->hdr_info.dynamic_info[i],
+ 0, sizeof(struct hdr_dynamic));
+ continue;
+ }
+ info->hdr_info.dynamic_info[i].type =
+ hdev->RXCap.hdr_dynamic_info[i].type;
+ info->hdr_info.dynamic_info[i].of_len =
+ hdev->RXCap.hdr_dynamic_info[i].hd_len - 3;
+ info->hdr_info.dynamic_info[i].support_flags =
+ hdev->RXCap.hdr_dynamic_info[i].support_flags;
+
+ for (j = 0; j < hdev->RXCap.hdr_dynamic_info[i].hd_len - 3; j++)
+ info->hdr_info.dynamic_info[i].optional_fields[j] =
+ hdev->RXCap.hdr_dynamic_info[i].optional_fields[j];
+ }
+ info->hdr_info.colorimetry_support =
+ hdev->RXCap.colorimetry_data;
+ info->hdr_info.lumi_max = hdev->RXCap.hdr_lum_max;
+ info->hdr_info.lumi_avg = hdev->RXCap.hdr_lum_avg;
+ info->hdr_info.lumi_min = hdev->RXCap.hdr_lum_min;
+ pr_info(SYS "update rx hdr info %x\n",
+ info->hdr_info.hdr_support);
+}
+
static int set_disp_mode_auto(void)
{
int ret = -1;
+
struct vinfo_s *info = NULL;
struct hdmitx_dev *hdev = &hdmitx_device;
struct hdmi_format_para *para = NULL;
if (!((strncmp(info->name, "480cvbs", 7) == 0) ||
(strncmp(info->name, "576cvbs", 7) == 0) ||
- (strncmp(info->name, "null", 4) == 0))) {
- info->hdr_info.hdr_support = (hdev->RXCap.hdr_sup_eotf_sdr << 0)
- | (hdev->RXCap.hdr_sup_eotf_hdr << 1)
- | (hdev->RXCap.hdr_sup_eotf_smpte_st_2084 << 2)
- | (hdev->RXCap.hdr_sup_eotf_hlg << 3);
- info->hdr_info.colorimetry_support =
- hdev->RXCap.colorimetry_data;
- info->hdr_info.lumi_max = hdev->RXCap.hdr_lum_max;
- info->hdr_info.lumi_avg = hdev->RXCap.hdr_lum_avg;
- info->hdr_info.lumi_min = hdev->RXCap.hdr_lum_min;
- pr_info(SYS "update rx hdr info %x\n",
- info->hdr_info.hdr_support);
- }
+ (strncmp(info->name, "null", 4) == 0)))
+ hdrinfo_to_vinfo(info, hdev);
+
hdmi_physcial_size_update(hdev);
/* If info->name equals to cvbs, then set mode to I mode to hdmi
struct device_attribute *attr, char *buf)
{
int pos = 0;
+ unsigned int i, j;
struct rx_cap *pRXCap = &(hdmitx_device.RXCap);
-
- pos += snprintf(buf + pos, PAGE_SIZE, "Supported EOTF:\n");
- pos += snprintf(buf + pos, PAGE_SIZE, " Traditional SDR: %d\n",
+ pos += snprintf(buf + pos, PAGE_SIZE, "HDR Static Metadata:\n");
+ pos += snprintf(buf + pos, PAGE_SIZE, " Supported EOTF:\n");
+ pos += snprintf(buf + pos, PAGE_SIZE, " Traditional SDR: %d\n",
pRXCap->hdr_sup_eotf_sdr);
- pos += snprintf(buf + pos, PAGE_SIZE, " Traditional HDR: %d\n",
+ pos += snprintf(buf + pos, PAGE_SIZE, " Traditional HDR: %d\n",
pRXCap->hdr_sup_eotf_hdr);
- pos += snprintf(buf + pos, PAGE_SIZE, " SMPTE ST 2084: %d\n",
+ pos += snprintf(buf + pos, PAGE_SIZE, " SMPTE ST 2084: %d\n",
pRXCap->hdr_sup_eotf_smpte_st_2084);
- pos += snprintf(buf + pos, PAGE_SIZE, " Hybrif Log-Gamma: %d\n",
+ pos += snprintf(buf + pos, PAGE_SIZE, " Hybrif Log-Gamma: %d\n",
pRXCap->hdr_sup_eotf_hlg);
- pos += snprintf(buf + pos, PAGE_SIZE, "Supported SMD type1: %d\n",
+ pos += snprintf(buf + pos, PAGE_SIZE, " Supported SMD type1: %d\n",
pRXCap->hdr_sup_SMD_type1);
- pos += snprintf(buf + pos, PAGE_SIZE, "Luminance Data\n");
- pos += snprintf(buf + pos, PAGE_SIZE, " Max: %d\n",
+ pos += snprintf(buf + pos, PAGE_SIZE, " Luminance Data\n");
+ pos += snprintf(buf + pos, PAGE_SIZE, " Max: %d\n",
pRXCap->hdr_lum_max);
- pos += snprintf(buf + pos, PAGE_SIZE, " Avg: %d\n",
+ pos += snprintf(buf + pos, PAGE_SIZE, " Avg: %d\n",
pRXCap->hdr_lum_avg);
- pos += snprintf(buf + pos, PAGE_SIZE, " Min: %d\n",
+ pos += snprintf(buf + pos, PAGE_SIZE, " Min: %d\n\n",
pRXCap->hdr_lum_min);
- pos += snprintf(buf + pos, PAGE_SIZE, " colorimetry_data: %x\n",
+ pos += snprintf(buf + pos, PAGE_SIZE, "HDR Dynamic Metadata:");
+
+ for (i = 0; i < 4; i++) {
+ if (pRXCap->hdr_dynamic_info[i].type == 0)
+ continue;
+ pos += snprintf(buf + pos, PAGE_SIZE,
+ "\n metadata_version: %x\n",
+ pRXCap->hdr_dynamic_info[i].type);
+ pos += snprintf(buf + pos, PAGE_SIZE,
+ " support_flags: %x\n",
+ pRXCap->hdr_dynamic_info[i].support_flags);
+ pos += snprintf(buf + pos, PAGE_SIZE,
+ " optional_fields:");
+ for (j = 0; j <
+ (pRXCap->hdr_dynamic_info[i].hd_len - 3); j++)
+ pos += snprintf(buf + pos, PAGE_SIZE, " %x",
+ pRXCap->hdr_dynamic_info[i].optional_fields[j]);
+ }
+
+ pos += snprintf(buf + pos, PAGE_SIZE, "\n\ncolorimetry_data: %x\n",
pRXCap->colorimetry_data);
return pos;
int i = 0;
for (i = 0; i < ARRAY_SIZE(map_fs); i++) {
- if (map_fs[i].rate == rate) {
- pr_info(AUD "aout notify rate %d\n",
- rate);
+ if (map_fs[i].rate == rate)
return map_fs[i].fs;
- }
}
pr_info(AUD "get FS_MAX\n");
return FS_MAX;
int i;
for (i = 0; i < ARRAY_SIZE(aud_size_map_ss); i++) {
- if (bits == aud_size_map_ss[i].sample_bits) {
- pr_info(AUD "aout notify size %d\n",
- bits);
+ if (bits == aud_size_map_ss[i].sample_bits)
return aud_size_map_ss[i].ss;
- }
}
pr_info(AUD "get SS_MAX\n");
return SS_MAX;
}
}
if (hdmitx_device.audio_param_update_flag == 0)
- pr_info(AUD "no update\n");
+ ;
else
hdmitx_device.audio_notify_flag = 1;
static void clear_hdr_info(struct hdmitx_dev *hdev)
{
struct vinfo_s *info = hdmitx_get_current_vinfo();
-
+ unsigned int i;
if (info) {
info->hdr_info.hdr_support = 0;
+ for (i = 0; i < 4; i++)
+ memset(&(info->hdr_info.dynamic_info[i]),
+ 0, sizeof(struct hdr_dynamic));
info->hdr_info.colorimetry_support = 0;
info->hdr_info.lumi_max = 0;
info->hdr_info.lumi_avg = 0;
{
const struct vinfo_s *info = NULL;
ssize_t len = 0;
+ unsigned int i, j;
info = get_current_vinfo2();
if (info == NULL)
info->master_display_info.white_point[1],
info->master_display_info.luminance[0],
info->master_display_info.luminance[1]);
- len += sprintf(buf+len, "hdr_info:\n"
+ len += sprintf(buf+len, "hdr_static_info:\n"
" hdr_support %d\n"
" lumi_max %d\n"
" lumi_avg %d\n"
info->hdr_info.lumi_max,
info->hdr_info.lumi_avg,
info->hdr_info.lumi_min);
+ len += sprintf(buf+len, "hdr_dynamic_info:");
+ for (i = 0; i < 4; i++) {
+ len += sprintf(buf+len,
+ "\n metadata_version: %x\n"
+ " support_flags: %x\n",
+ info->hdr_info.dynamic_info[i].type,
+ info->hdr_info.dynamic_info[i].support_flags);
+ len += sprintf(buf+len, " optional_fields: ");
+ for (j = 0; j < info->
+ hdr_info.dynamic_info[i].of_len; j++) {
+ len += sprintf(buf+len, " %x",
+ info->hdr_info.dynamic_info[i].
+ optional_fields[j]);
+ }
+ }
+ len += sprintf(buf+len, "\n");
return len;
}
baseinfo.screen_real_height = info->screen_real_height;
baseinfo.video_clk = info->video_clk;
baseinfo.viu_color_fmt = info->viu_color_fmt;
- baseinfo.hdr_info = info->hdr_info;
if (copy_to_user(argp, &baseinfo,
sizeof(struct vinfo_base_s)))
ret = -EFAULT;
{
const struct vinfo_s *info = NULL;
ssize_t len = 0;
+ unsigned int i, j;
info = get_current_vinfo();
if (info == NULL)
info->master_display_info.white_point[1],
info->master_display_info.luminance[0],
info->master_display_info.luminance[1]);
- len += sprintf(buf+len, "hdr_info:\n"
+ len += sprintf(buf+len, "hdr_static_info:\n"
" hdr_support %d\n"
" lumi_max %d\n"
" lumi_avg %d\n"
info->hdr_info.lumi_max,
info->hdr_info.lumi_avg,
info->hdr_info.lumi_min);
+ len += sprintf(buf+len, "hdr_dynamic_info:");
+ for (i = 0; i < 4; i++) {
+ len += sprintf(buf+len,
+ "\n metadata_version: %x\n"
+ " support_flags: %x\n",
+ info->hdr_info.dynamic_info[i].type,
+ info->hdr_info.dynamic_info[i].support_flags);
+ len += sprintf(buf+len, " optional_fields: ");
+ for (j = 0; j <
+ info->hdr_info.dynamic_info[i].of_len; j++) {
+ len += sprintf(buf+len, " %x",
+ info->hdr_info.dynamic_info[i].
+ optional_fields[j]);
+ }
+ }
+ len += sprintf(buf+len, "\n");
return len;
}
baseinfo.screen_real_height = info->screen_real_height;
baseinfo.video_clk = info->video_clk;
baseinfo.viu_color_fmt = info->viu_color_fmt;
- baseinfo.hdr_info = info->hdr_info;
if (copy_to_user(argp, &baseinfo,
sizeof(struct vinfo_base_s)))
ret = -EFAULT;
#include <linux/pinctrl/consumer.h>
/* HDMITX driver version */
-#define HDMITX_VER "20180702"
+#define HDMITX_VER "20180808"
/* chip type */
#define MESON_CPU_ID_M8B 0
VID_EN, VID_DIS, AUD_EN, AUD_DIS, EDID_EN, EDID_DIS, HDCP_EN, HDCP_DIS,
};
+struct hdr_dynamic_struct {
+ unsigned int type;
+ unsigned int hd_len;/*hdr_dynamic_length*/
+ unsigned char support_flags;
+ unsigned char optional_fields[20];
+};
+
struct rx_cap {
unsigned int native_Mode;
/*video*/
unsigned char hdr_lum_max;
unsigned char hdr_lum_avg;
unsigned char hdr_lum_min;
+ struct hdr_dynamic_struct hdr_dynamic_info[4];
unsigned char IDManufacturerName[4];
unsigned char IDProductCode[2];
unsigned char IDSerialNumber[4];
u32 max_content; /* Maximum Content Light Level */
u32 max_frame_average; /* Maximum Frame-average Light Level */
};
+/*
+ *hdr_dynamic_type
+ * 0x0001: type_1_hdr_metadata_version
+ * 0x0002: ts_103_433_spec_version
+ * 0x0003: itu_t_h265_spec_version
+ * 0x0004: type_4_hdr_metadata_version
+ */
+struct hdr_dynamic {
+ unsigned int type;
+ unsigned char support_flags;
+ unsigned int of_len; /*optional_fields length*/
+ unsigned char optional_fields[28];
+};
struct hdr_info {
- u32 hdr_support; /* RX EDID hdr support types */
- /*bit7:BT2020RGB bit6:BT2020YCC bit5:BT2020cYCC bit4:adobeRGB*/
- /*bit3:adobeYCC601 bit2:sYCC601 bit1:xvYCC709 bit0:xvYCC601*/
+/* RX EDID hdr support types */
+ u32 hdr_support;
+/*
+ *dynamic_info[0] expresses type1's parameters certainly
+ *dynamic_info[1] expresses type2's parameters certainly
+ *dynamic_info[2] expresses type3's parameters certainly
+ *dynamic_info[3] expresses type4's parameters certainly
+ *if some types don't exist, the corresponding dynamic_info
+ *is zero instead of inexistence
+ */
+ struct hdr_dynamic dynamic_info[4];
+/*bit7:BT2020RGB bit6:BT2020YCC bit5:BT2020cYCC bit4:adobeRGB*/
+/*bit3:adobeYCC601 bit2:sYCC601 bit1:xvYCC709 bit0:xvYCC601*/
u8 colorimetry_support; /* RX EDID colorimetry support types */
u32 lumi_max; /* RX EDID Lumi Max value */
u32 lumi_avg; /* RX EDID Lumi Avg value */
u32 screen_real_height;
u32 video_clk;
enum color_fmt_e viu_color_fmt;
- struct hdr_info hdr_info;
};
struct vinfo_s {