hdmirx: add edid data splice function [1/1]

PD#SWPL-8467

Problem:
1.no index parse for edid data block
2.no earc capabilities data structure parse
3.no earc cap data structure splice function
4.no cta data block splice/remove function

Solution:
1.add edid data block index parse
2.add earc capabilities data structure parse
3.add splice function of earc cap data structure
4.add splice/remove function of data block to edid

Verify:
TL1

Change-Id: I47b9f2176c31c65a08cdc657c00398f88cbdd7d3
Signed-off-by: Hang Cheng <hang.cheng@amlogic.com>
This commit is contained in:
Hang Cheng
2019-05-16 10:20:08 +08:00
committed by Jianxin Pan
parent b949c1a39a
commit 7447ea231f
5 changed files with 1647 additions and 398 deletions

View File

@@ -1622,6 +1622,43 @@ static ssize_t get_reset_hdcp22(struct device *dev,
{
return 0;
}
static ssize_t earc_cap_ds_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return 0;
}
static ssize_t earc_cap_ds_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
unsigned char char_len = 0;
unsigned int data = 0;
unsigned char i = 0;
unsigned char tmp[3] = {0};
unsigned char earc_cap_ds[EARC_CAP_DS_MAX_LENGTH] = {0};
int ret = 0;
char_len = strlen(buf);
rx_pr("character length = %d\n", char_len);
for (i = 0; i < char_len/2; i++) {
tmp[2] = '\0';
memcpy(tmp, buf + 2*i, 2);
ret = kstrtouint(tmp, 16, &data);
if (ret < 0) {
rx_pr("kstrtouint failed\n");
return count;
}
earc_cap_ds[i] = data;
}
rx_pr("eARC cap ds len: %d\n", i);
rx_set_earc_cap_ds(earc_cap_ds, i);
return count;
}
static DEVICE_ATTR(debug, 0644, hdmirx_debug_show, hdmirx_debug_store);
static DEVICE_ATTR(edid, 0644, hdmirx_edid_show, hdmirx_edid_store);
static DEVICE_ATTR(key, 0644, hdmirx_key_show, hdmirx_key_store);
@@ -1637,6 +1674,7 @@ static DEVICE_ATTR(hdcp_version, 0644, hdcp_version_show, hdcp_version_store);
static DEVICE_ATTR(hw_info, 0644, hw_info_show, hw_info_store);
static DEVICE_ATTR(edid_dw, 0644, edid_dw_show, edid_dw_store);
static DEVICE_ATTR(ksvlist, 0644, ksvlist_show, ksvlist_store);
static DEVICE_ATTR(earc_cap_ds, 0644, earc_cap_ds_show, earc_cap_ds_store);
static int hdmirx_add_cdev(struct cdev *cdevp,
const struct file_operations *fops,
@@ -2162,6 +2200,11 @@ static int hdmirx_probe(struct platform_device *pdev)
rx_pr("hdmirx: fail to create ksvlist file\n");
goto fail_create_ksvlist;
}
ret = device_create_file(hdevp->dev, &dev_attr_earc_cap_ds);
if (ret < 0) {
rx_pr("hdmirx: fail to create earc_cap_ds file\n");
goto fail_create_earc_cap_ds;
}
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!res) {
@@ -2353,7 +2396,13 @@ static int hdmirx_probe(struct platform_device *pdev)
disable_port_en = (disable_port >> 4) & 0x1;
disable_port_num = disable_port & 0xF;
}
ret = of_property_read_u32(pdev->dev.of_node,
"arc_port", &rx.arc_port);
if (ret) {
/* default arc port is port B */
rx.arc_port = 0x1;
rx_pr("not find arc_port, portB by default\n");
}
ret = of_reserved_mem_device_init(&(pdev->dev));
if (ret != 0)
rx_pr("warning: no rev cmd mem\n");
@@ -2380,6 +2429,8 @@ fail_kmalloc_pd_fifo:
return ret;
fail_get_resource_irq:
return ret;
fail_create_earc_cap_ds:
device_remove_file(hdevp->dev, &dev_attr_earc_cap_ds);
fail_create_ksvlist:
device_remove_file(hdevp->dev, &dev_attr_ksvlist);
fail_create_edid_dw:
@@ -2447,6 +2498,7 @@ static int hdmirx_remove(struct platform_device *pdev)
device_remove_file(hdevp->dev, &dev_attr_esm_base);
device_remove_file(hdevp->dev, &dev_attr_info);
device_remove_file(hdevp->dev, &dev_attr_arc_aud_type);
device_remove_file(hdevp->dev, &dev_attr_earc_cap_ds);
device_remove_file(hdevp->dev, &dev_attr_ksvlist);
device_remove_file(hdevp->dev, &dev_attr_edid_dw);
device_remove_file(hdevp->dev, &dev_attr_hw_info);

View File

@@ -46,7 +46,7 @@
*
*
*/
#define RX_VER2 "ver.2019/05/08"
#define RX_VER2 "ver.2019/05/18"
/*print type*/
#define LOG_EN 0x01
@@ -449,6 +449,7 @@ struct rx_s {
/*struct pd_infoframe_s dbg_info;*/
struct phy_sts phy;
struct emp_buff empbuff;
uint32_t arc_port;
};
struct _hdcp_ksv {

File diff suppressed because it is too large Load Diff

View File

@@ -17,20 +17,26 @@
#ifndef _HDMI_RX_EDID_H_
#define _HDMI_RX_EDID_H_
#define EDID_EXT_BLK_OFF 128
#define EDID_SIZE 256
#define EDID_HDR_SIZE 7
#define EDID_HDR_HEAD_LEN 4
#define MAX_HDR_LUMI_LEN 3
#define MAX_EDID_BUF_SIZE 512
/* CEA861F Table 44~46 CEA data block tag code*/
/* CTA-861G Table 54~57 CTA data block tag codes */
/* tag code 0x0: reserved */
#define AUDIO_TAG 0x1
#define VIDEO_TAG 0x2
#define VENDOR_TAG 0x3
/* tag of HF-VSDB is the same as VSDB
* so add an offset(0xF0) for HF-VSDB
*/
#define HF_VSDB_OFFSET 0xF0
#define HF_VENDOR_DB_TAG (VENDOR_TAG + HF_VSDB_OFFSET)
#define SPEAKER_TAG 0x4
/* VESA Display Transfer Characteristic Data Block */
#define VESA_TAG 0x5
#define VDTCDB_TAG 0x5
/* tag code 0x6: reserved */
#define USE_EXTENDED_TAG 0x7
@@ -38,22 +44,40 @@
#define VCDB_TAG 0 /* video capability data block */
#define VSVDB_TAG 1 /* Vendor-Specific Video Data Block */
#define VDDDB_TAG 2 /* VESA Display Device Data Block */
#define VVTDB_TAG 3 /* VESA Video Timing Block Extension */
/* extend tag code 0x4: Reserved for HDMI Video Data Block*/
#define VVTBE_TAG 3 /* VESA Video Timing Block Extension */
/* extend tag code 0x4: Reserved for HDMI Video Data Block */
#define CDB_TAG 5 /* Colorimetry Data Block */
#define HDR_TAG 6 /* HDR Static Metadata Data Block */
/* extend tag code 7-12: reserved */
#define HDR_STATIC_TAG 6 /* HDR Static Metadata Data Block */
#define HDR_DYNAMIC_TAG 7 /* HDR Dynamic Metadata Data Block */
/* extend tag code 8-12: reserved */
#define VFPDB_TAG 13 /* Video Format Preference Data Block */
#define Y420VDB_TAG 14 /* YCBCR 4:2:0 Video Data Block */
#define Y420CMDB_TAG 15 /* YCBCR 4:2:0 Capability Map Data Block */
/* extend tag code 16: Reserved */
/* extend tag code 16: Reserved for CTA Miscellaneous Audio Fields */
#define VSADB_TAG 17 /* Vendor-Specific Audio Data Block */
/* extend tag code 18~31: Reserved */
/* extend tag code 18: Reserved for HDMI Audio Data Block */
#define RCDB_TAG 19 /* Room Configuration Data Block */
#define SLDB_TAG 20 /* Speaker Location Data Block */
/* extend tag code 21~31: Reserved */
#define IFDB_TAG 32 /* infoframe data block */
#define HDMI_VIC420_OFFSET 0x100
#define HDMI_3D_OFFSET 0x180
#define HDMI_VESA_OFFSET 0x200
/* eARC Rx Capabilities Data Structure version */
#define CAP_DS_VER 0x1
/* eARC Rx Capabilities Data Structure Maximum Length */
#define EARC_CAP_DS_MAX_LENGTH 256
/* eARC Rx Capability data structure End Marker */
#define EARC_CAP_DS_END_MARKER 0x00
#define EARC_CAP_BLOCK_MAX 3
#define DATA_BLK_MAX_NUM 32
#define TAG_MAX 0xFF
/* data block max length(include head): 0x1F+1 */
#define DB_LEN_MAX 32
/* short audio descriptor length */
#define SAD_LEN 3
#define BLK_LENGTH(a) (a & 0x1F)
enum edid_audio_format_e {
AUDIO_FORMAT_HEADER,
@@ -81,6 +105,16 @@ enum edid_tag_e {
EDID_TAG_HDR = ((0x7<<8)|6),
};
union bit_rate_u {
struct pcm_t {
unsigned char size_16bit:1;
unsigned char size_20bit:1;
unsigned char size_24bit:1;
unsigned char size_reserv:5;
} pcm;
unsigned char others;
};
struct edid_audio_block_t {
unsigned char max_channel:3;
unsigned char format_code:4;
@@ -94,15 +128,7 @@ struct edid_audio_block_t {
unsigned char freq_176_4khz:1;
unsigned char freq_192khz:1;
unsigned char freq_reserv:1;
union bit_rate_u {
struct pcm_t {
unsigned char size_16bit:1;
unsigned char size_20bit:1;
unsigned char size_24bit:1;
unsigned char size_reserv:5;
} pcm;
unsigned char others;
} bit_rate;
union bit_rate_u bit_rate;
};
struct edid_hdr_block_t {
@@ -151,6 +177,7 @@ struct audio_db_s {
struct edid_audio_block_t sad[15];
};
/* may need extend spker alloc from CTA-SPEC */
/* speaker allocation data block: 3 bytes*/
struct speaker_alloc_db_s {
unsigned char flw_frw:1;
@@ -358,38 +385,14 @@ struct dv_vsvdb_s {
uint8_t dm_minor_ver;
};
struct edid_info_s {
/* 8 */
unsigned char manufacturer_name[3];
/* 10 */
unsigned int product_code;
/* 12 */
unsigned int serial_number;
/* 16 */
unsigned char product_week;
unsigned int product_year;
unsigned char edid_version;
unsigned char edid_revision;
/* 54 + 18 * x */
struct detailed_timing_desc descriptor1;
struct detailed_timing_desc descriptor2;
/* 54 + 18 * x */
unsigned char monitor_name[13];
unsigned int max_sup_pixel_clk;
uint8_t extension_flag;
/* 127 */
unsigned char block0_chk_sum;
struct cta_data_blk_info {
unsigned char cta_blk_index;
uint16_t tag_code;
unsigned char offset;
unsigned char blk_len;
};
/* CEA extension */
/* CEA header */
unsigned char cea_tag;
unsigned char cea_revision;
unsigned char dtd_offset;
unsigned char underscan_sup:1;
unsigned char basic_aud_sup:1;
unsigned char ycc444_sup:1;
unsigned char ycc422_sup:1;
unsigned char native_dtd_num:4;
struct cta_blk_parse_info {
/* audio data block */
struct video_db_s video_db;
/* audio data block */
@@ -425,6 +428,63 @@ struct edid_info_s {
bool contain_y420_cmdb;
unsigned char y420_all_vic;
unsigned char y420_cmdb_vic[31];
bool contain_vsadb;
unsigned int vsadb_ieee;
/* CTA-861-G 7.5.8 27-2-3 */
unsigned char vsadb_payload[22];
unsigned char data_blk_num;
struct cta_data_blk_info db_info[DATA_BLK_MAX_NUM];
};
/* CEA extension */
struct cea_ext_parse_info {
/* CEA header */
unsigned char cea_tag;
unsigned char cea_revision;
unsigned char dtd_offset;
unsigned char underscan_sup:1;
unsigned char basic_aud_sup:1;
unsigned char ycc444_sup:1;
unsigned char ycc422_sup:1;
unsigned char native_dtd_num:4;
struct cta_blk_parse_info blk_parse_info;
};
struct edid_info_s {
/* 8 */
unsigned char manufacturer_name[3];
/* 10 */
unsigned int product_code;
/* 12 */
unsigned int serial_number;
/* 16 */
unsigned char product_week;
unsigned int product_year;
unsigned char edid_version;
unsigned char edid_revision;
/* 54 + 18 * x */
struct detailed_timing_desc descriptor1;
struct detailed_timing_desc descriptor2;
/* 54 + 18 * x */
unsigned char monitor_name[13];
unsigned int max_sup_pixel_clk;
uint8_t extension_flag;
/* 127 */
unsigned char block0_chk_sum;
struct cea_ext_parse_info cea_ext_info;
int free_size;
unsigned char total_free_size;
unsigned char dtd_size;
};
struct cta_blk_pair {
uint16_t tag_code;
char *blk_name;
};
struct edid_data_s {
@@ -440,6 +500,19 @@ enum tx_hpd_event_e {
E_RCV = 2,
};
struct cap_block_s {
unsigned char block_id;
unsigned char payload_len;
unsigned char offset;
};
struct earc_cap_ds {
unsigned char cap_ds_len;
unsigned char cap_ds_ver;
struct cap_block_s cap_block[EARC_CAP_BLOCK_MAX];
struct cta_blk_parse_info blk_parse_info;
};
enum hdmi_vic_e {
/* Refer to CEA 861-D */
HDMI_UNKNOWN = 0,
@@ -615,10 +688,21 @@ enum hdmi_vic_e {
HDMI_UNSUPPORT,
};
enum earc_cap_block_id {
EARC_CAP_BLOCK_ID_0 = 0,
EARC_CAP_BLOCK_ID_1 = 1,
EARC_CAP_BLOCK_ID_2 = 2,
EARC_CAP_BLOCK_ID_3 = 3
};
extern int edid_mode;
extern int port_map;
extern bool new_hdr_lum;
extern bool atmos_edid_update_hpd_en;
extern bool en_take_dtd_space;
extern bool earc_cap_ds_update_hpd_en;
extern unsigned char edid_temp[EDID_SIZE];
int rx_set_hdr_lumi(unsigned char *data, int len);
void rx_edid_physical_addr(int a, int b, int c, int d);
unsigned char rx_parse_arc_aud_type(const unsigned char *buff);
@@ -626,8 +710,23 @@ extern unsigned int hdmi_rx_top_edid_update(void);
unsigned char rx_get_edid_index(void);
unsigned char *rx_get_edid(int edid_index);
void edid_parse_block0(uint8_t *p_edid, struct edid_info_s *edid_info);
void edid_parse_cea_block(uint8_t *p_edid, struct edid_info_s *edid_info);
void edid_parse_cea_ext_block(uint8_t *p_edid,
struct cea_ext_parse_info *blk_parse_info);
void rx_edid_parse(uint8_t *p_edid, struct edid_info_s *edid_info);
void rx_edid_parse_print(struct edid_info_s *edid_info);
void rx_blk_index_print(struct cta_blk_parse_info *blk_info);
int rx_edid_free_size(uint8_t *cur_edid, int size);
unsigned char rx_edid_total_free_size(unsigned char *cur_edid,
unsigned int size);
unsigned char rx_get_cea_dtd_size(unsigned char *cur_edid, unsigned int size);
bool rx_set_earc_cap_ds(unsigned char *data, unsigned int len);
void rx_prase_earc_capds_dbg(void);
void edid_splice_earc_capds(unsigned char *p_edid,
unsigned char *earc_cap_ds, unsigned int len);
void edid_splice_earc_capds_dbg(uint8_t *p_edid);
void edid_splice_data_blk_dbg(uint8_t *p_edid, uint8_t idx);
void edid_rm_db_by_tag(uint8_t *p_edid, uint16_t tagid);
void edid_rm_db_by_idx(uint8_t *p_edid, uint8_t blk_idx);
void rx_modify_edid(unsigned char *buffer,
int len, unsigned char *addition);
void rx_edid_update_audio_info(unsigned char *p_edid,

View File

@@ -1730,6 +1730,10 @@ int rx_set_global_variable(const char *buf, int size)
return pr_var(pll_lock_max, index);
if (set_pr_var(tmpbuf, clock_lock_th, value, &index, ret))
return pr_var(clock_lock_th, index);
if (set_pr_var(tmpbuf, en_take_dtd_space, value, &index, ret))
return pr_var(en_take_dtd_space, index);
if (set_pr_var(tmpbuf, earc_cap_ds_update_hpd_en, value, &index, ret))
return pr_var(earc_cap_ds_update_hpd_en, index);
return 0;
}
@@ -1841,6 +1845,8 @@ void rx_get_global_variable(const char *buf)
pr_var(top_intr_maskn_value, i++);
pr_var(pll_lock_max, i++);
pr_var(clock_lock_th, i++);
pr_var(en_take_dtd_space, i++);
pr_var(earc_cap_ds_update_hpd_en, i++);
}
void skip_frame(unsigned int cnt)
@@ -2784,8 +2790,6 @@ int hdmirx_debug(const char *buf, int size)
char *token;
char *cur;
int cnt = 0;
unsigned char edid_index;
unsigned char *pedid_data;
struct edid_info_s edid_info;
while ((buf[i]) && (buf[i] != ',') && (buf[i] != ' ')) {
@@ -2871,12 +2875,26 @@ int hdmirx_debug(const char *buf, int size)
} else if (strncmp(input[0], "pktinfo", 7) == 0) {
rx_debug_pktinfo(input);
} else if (strncmp(tmpbuf, "parse_edid", 10) == 0) {
edid_index = rx_get_edid_index();
pedid_data = rx_get_edid(edid_index);
memset(&edid_info, 0, sizeof(struct edid_info_s));
edid_parse_block0(pedid_data, &edid_info);
edid_parse_cea_block(pedid_data+128, &edid_info);
rx_edid_parse(edid_temp, &edid_info);
rx_edid_parse_print(&edid_info);
rx_blk_index_print(&edid_info.cea_ext_info.blk_parse_info);
} else if (strncmp(tmpbuf, "parse_capds", 11) == 0) {
rx_prase_earc_capds_dbg();
} else if (strncmp(tmpbuf, "splice_capds", 12) == 0) {
edid_splice_earc_capds_dbg(edid_temp);
} else if (strncmp(tmpbuf, "splice_db", 9) == 0) {
if (kstrtou32(tmpbuf + 9, 16, &value) < 0)
return -EINVAL;
edid_splice_data_blk_dbg(edid_temp, value);
} else if (strncmp(tmpbuf, "rm_db_tag", 9) == 0) {
if (kstrtou32(tmpbuf + 9, 16, &value) < 0)
return -EINVAL;
edid_rm_db_by_tag(edid_temp, value);
} else if (strncmp(tmpbuf, "rm_db_idx", 9) == 0) {
if (kstrtou32(tmpbuf + 9, 16, &value) < 0)
return -EINVAL;
edid_rm_db_by_idx(edid_temp, value);
} else if (tmpbuf[0] == 'w') {
rx_debug_wr_reg(buf, tmpbuf, i);
} else if (tmpbuf[0] == 'r') {