mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
hdmirx: add lock for top sw reset & edid size protect [1/2]
PD#170713: hdmirx: add lock for top sw reset & edid size protect Change-Id: I97502324d01d2e99d3a30bb1829affef5d2c123b Signed-off-by: hongmin hua <hongmin.hua@amlogic.com> Signed-off-by: Zongdong Jiao <zongdong.jiao@amlogic.com>
This commit is contained in:
@@ -572,6 +572,9 @@ void hdmirx_set_timing_info(struct tvin_sig_property_s *prop)
|
||||
prop->ve = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* hdmirx_get_connect_info - get 5v info
|
||||
*/
|
||||
int hdmirx_get_connect_info(void)
|
||||
{
|
||||
return pwr_sts;
|
||||
|
||||
@@ -46,15 +46,25 @@
|
||||
*
|
||||
*
|
||||
*/
|
||||
#define RX_VER2 "ver.2018/07/30"
|
||||
#define RX_VER2 "ver.2018/07/30a"
|
||||
|
||||
/*print type*/
|
||||
#define LOG_EN 0x01
|
||||
#define VIDEO_LOG 0x02
|
||||
#define AUDIO_LOG 0x04
|
||||
#define HDCP_LOG 0x08
|
||||
#define PACKET_LOG 0x10
|
||||
#define EQ_LOG 0x20
|
||||
#define REG_LOG 0x40
|
||||
#define ERR_LOG 0x80
|
||||
#define VSI_LOG 0x800
|
||||
|
||||
/* 50ms timer for hdmirx main loop (HDMI_STATE_CHECK_FREQ is 20) */
|
||||
|
||||
|
||||
#define ABS(x) ((x) < 0 ? -(x) : (x))
|
||||
|
||||
|
||||
#define EDID_MIX_MAX_SIZE 64
|
||||
|
||||
#define ESM_KILL_WAIT_TIMES 250
|
||||
#define str_cmp(buff, str) ((strlen((str)) == strlen((buff))) && \
|
||||
@@ -366,6 +376,7 @@ struct rx_s {
|
||||
struct aud_info_s aud_info;
|
||||
struct vsi_info_s vs_info_details;
|
||||
struct tvin_hdr_info_s hdr_info;
|
||||
unsigned char edid_mix_buf[EDID_MIX_MAX_SIZE];
|
||||
unsigned int pwr_sts;
|
||||
/* for debug */
|
||||
/*struct pd_infoframe_s dbg_info;*/
|
||||
|
||||
@@ -515,7 +515,8 @@ void rx_edid_update_hdr_info(
|
||||
{
|
||||
u_char hdr_edid[EDID_HDR_SIZE];
|
||||
|
||||
if (p_edid == NULL)
|
||||
if ((p_edid == NULL) || ((receive_hdr_lum[0] == 0)
|
||||
&& (receive_hdr_lum[1] == 0) && (receive_hdr_lum[2] == 0)))
|
||||
return;
|
||||
/*check if data is updated*/
|
||||
if (!(receive_hdr_lum[0] | receive_hdr_lum[1]
|
||||
@@ -534,17 +535,284 @@ unsigned int rx_exchange_bits(unsigned int value)
|
||||
{
|
||||
unsigned int temp;
|
||||
|
||||
rx_pr("bfe:%#x\n", value);
|
||||
temp = value & 0xF;
|
||||
value = (((value >> 4) & 0xF) | (value & 0xFFF0));
|
||||
value = ((value & 0xFF0F) | (temp << 4));
|
||||
temp = value & 0xF00;
|
||||
value = (((value >> 4) & 0xF00) | (value & 0xF0FF));
|
||||
value = ((value & 0x0FFF) | (temp << 4));
|
||||
rx_pr("aft:%#x\n", value);
|
||||
return value;
|
||||
}
|
||||
|
||||
int rx_get_tag_code(uint8_t *edid_data)
|
||||
{
|
||||
int tag_code;
|
||||
|
||||
if ((*edid_data >> 5) != 7)
|
||||
tag_code = (*edid_data >> 5);
|
||||
else
|
||||
tag_code = (7 << 8) | *(edid_data + 1);/*extern tag*/
|
||||
|
||||
return tag_code;
|
||||
}
|
||||
|
||||
int rx_get_ceadata_offset(uint8_t *cur_edid, uint8_t *addition)
|
||||
{
|
||||
int i;
|
||||
int type;
|
||||
|
||||
if ((cur_edid == NULL) || (addition == NULL))
|
||||
return 0;
|
||||
|
||||
type = rx_get_tag_code(addition);
|
||||
i = EDID_DEFAULT_START;/*block check start index*/
|
||||
while (i < 255) {
|
||||
if (type == rx_get_tag_code(cur_edid + i))
|
||||
return i;
|
||||
i += (1 + (*(cur_edid + i) & 0x1f));
|
||||
}
|
||||
if (log_level & VIDEO_LOG)
|
||||
rx_pr("type: %#x, start addr: %#x\n", type, i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rx_mix_edid_audio(uint8_t *cur_data, uint8_t *addition)
|
||||
{
|
||||
struct edid_audio_block_t *ori_data;
|
||||
struct edid_audio_block_t *add_data;
|
||||
unsigned char ori_len, add_len;
|
||||
int i, j;
|
||||
|
||||
if ((cur_data == 0) || (addition == 0) ||
|
||||
(*cur_data >> 5) != (*addition >> 5))
|
||||
return;
|
||||
|
||||
ori_data = (struct edid_audio_block_t *)(cur_data + 1);
|
||||
add_data = (struct edid_audio_block_t *)(addition + 1);
|
||||
ori_len = (*cur_data & 0x1f)/FORMAT_SIZE;
|
||||
add_len = (*addition & 0x1f)/FORMAT_SIZE;
|
||||
if (log_level & VIDEO_LOG)
|
||||
rx_pr("mix audio format ori len:%d,add len:%d\n",
|
||||
ori_len, add_len);
|
||||
for (i = 0; i < add_len; i++) {
|
||||
if (log_level & VIDEO_LOG)
|
||||
rx_pr("mix audio format:%d\n", add_data[i].format_code);
|
||||
/*only support lpcm dts dd+*/
|
||||
if (!is_audio_support(add_data[i].format_code))
|
||||
continue;
|
||||
/*mix audio data*/
|
||||
for (j = 0; j < ori_len; j++) {
|
||||
if (ori_data[j].format_code ==
|
||||
add_data[i].format_code) {
|
||||
if (log_level & VIDEO_LOG)
|
||||
rx_pr("mix audio mix format:%d\n",
|
||||
add_data[i].format_code);
|
||||
/*choose channel is lager*/
|
||||
ori_data[j].max_channel =
|
||||
((ori_data[j].max_channel >
|
||||
add_data[i].max_channel) ?
|
||||
ori_data[j].max_channel :
|
||||
add_data[i].max_channel);
|
||||
/*mix sample freqence*/
|
||||
*(((unsigned char *)&ori_data[j]) + 1) =
|
||||
*(((unsigned char *)&ori_data[j]) + 1) |
|
||||
*(((unsigned char *)&add_data[i]) + 1);
|
||||
/*mix bit rate*/
|
||||
if (add_data[i].format_code ==
|
||||
AUDIO_FORMAT_LPCM)
|
||||
*(((unsigned char *)&ori_data[j]) + 2) =
|
||||
*(((unsigned char *)&ori_data[j]) + 2) |
|
||||
*(((unsigned char *)&add_data[i]) + 2);
|
||||
else
|
||||
ori_data[j].bit_rate.others =
|
||||
add_data[i].bit_rate.others;
|
||||
break;
|
||||
}
|
||||
if (j == (ori_len - 1)) {
|
||||
if (log_level & VIDEO_LOG)
|
||||
rx_pr("mix audio add new format: %d\n",
|
||||
add_data[i].format_code);
|
||||
if (((*cur_data & 0x1f) + FORMAT_SIZE)
|
||||
<= 0x1f) {
|
||||
memcpy(cur_data +
|
||||
(*cur_data & 0x1f) + 1,
|
||||
&add_data[i], FORMAT_SIZE);
|
||||
*cur_data += FORMAT_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rx_mix_edid_hdr(uint8_t *cur_data, uint8_t *addition)
|
||||
{
|
||||
struct edid_hdr_block_t *cur_block;
|
||||
struct edid_hdr_block_t *add_block;
|
||||
|
||||
if ((cur_data == 0) || (addition == 0) ||
|
||||
(*cur_data >> 5) != (*addition >> 5))
|
||||
return;
|
||||
|
||||
cur_block = (struct edid_hdr_block_t *)(cur_data + 1);
|
||||
add_block = (struct edid_hdr_block_t *)(addition + 1);
|
||||
if (add_block->max_lumi | add_block->avg_lumi |
|
||||
add_block->min_lumi) {
|
||||
cur_block->max_lumi = add_block->max_lumi;
|
||||
cur_block->avg_lumi = add_block->avg_lumi;
|
||||
cur_block->min_lumi = add_block->min_lumi;
|
||||
if ((*cur_data & 0x1f) < (*addition & 0x1f))
|
||||
*cur_data = *addition;
|
||||
}
|
||||
}
|
||||
|
||||
int rx_edid_free_size(uint8_t *cur_edid, int size)
|
||||
{
|
||||
int block_start;
|
||||
|
||||
if (cur_edid == 0)
|
||||
return -1;
|
||||
/*get description offset*/
|
||||
block_start = cur_edid[EDID_BLOCK1_OFFSET +
|
||||
EDID_DESCRIP_OFFSET];
|
||||
block_start += EDID_BLOCK1_OFFSET;
|
||||
if (log_level & VIDEO_LOG)
|
||||
rx_pr("%s block_start:%d\n", __func__, block_start);
|
||||
/*find the empty data index*/
|
||||
while ((cur_edid[block_start] > 0) &&
|
||||
(block_start < size)) {
|
||||
if (log_level & VIDEO_LOG)
|
||||
rx_pr("%s running:%d\n", __func__, block_start);
|
||||
if ((cur_edid[block_start] & 0x1f) == 0)
|
||||
break;
|
||||
block_start += DETAILED_TIMING_LEN;
|
||||
}
|
||||
if (log_level & VIDEO_LOG)
|
||||
rx_pr("%s block_start end:%d\n", __func__, block_start);
|
||||
/*compute the free size*/
|
||||
if (block_start < (size - 1))
|
||||
return (size - block_start - 1);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
void rx_mix_block(uint8_t *cur_data, uint8_t *addition)
|
||||
{
|
||||
int tag_code;
|
||||
|
||||
if ((cur_data == 0) || (addition == 0) ||
|
||||
(*cur_data >> 5) != (*addition >> 5))
|
||||
return;
|
||||
if (log_level & VIDEO_LOG)
|
||||
rx_pr("before type:%d - %d,len:%d - %d\n",
|
||||
(*cur_data >> 5), (*addition >> 5),
|
||||
(*cur_data & 0x1f), (*addition & 0x1f));
|
||||
|
||||
tag_code = rx_get_tag_code(cur_data);
|
||||
|
||||
switch (tag_code) {
|
||||
case EDID_TAG_AUDIO:
|
||||
rx_mix_edid_audio(cur_data, addition);
|
||||
break;
|
||||
|
||||
case EDID_TAG_HDR:
|
||||
rx_mix_edid_hdr(cur_data, addition);
|
||||
break;
|
||||
}
|
||||
if (log_level & VIDEO_LOG)
|
||||
rx_pr("end type:%d - %d,len:%d - %d\n",
|
||||
(*cur_data >> 5), (*addition >> 5),
|
||||
(*cur_data & 0x1f), (*addition & 0x1f));
|
||||
}
|
||||
|
||||
void rx_modify_edid(unsigned char *buffer,
|
||||
int len, unsigned char *addition)
|
||||
{
|
||||
int start_addr = 0;/*the addr in edid need modify*/
|
||||
int start_addr_temp = 0;/*edid_temp start addr*/
|
||||
int temp_len = 0;
|
||||
unsigned char *cur_data = rx.edid_mix_buf;
|
||||
int addition_size = 0;
|
||||
int cur_size = 0;
|
||||
int i, free_size;
|
||||
|
||||
if ((len <= 255) || (buffer == 0) || (addition == 0))
|
||||
return;
|
||||
|
||||
/*get the mix block value*/
|
||||
if (*addition & 0x1f) {
|
||||
/*get addition block index in local edid*/
|
||||
start_addr = rx_get_ceadata_offset(buffer, addition);
|
||||
if (log_level & VIDEO_LOG)
|
||||
rx_pr("%s start addr:%d\n", __func__, start_addr);
|
||||
if (start_addr > EDID_DEFAULT_START) {
|
||||
cur_size = (*(buffer + start_addr) & 0x1f) + 1;
|
||||
addition_size = (*addition & 0x1f) + 1;
|
||||
if (sizeof(rx.edid_mix_buf) >=
|
||||
(cur_size + addition_size))
|
||||
memcpy(cur_data, buffer + start_addr, cur_size);
|
||||
else
|
||||
return;
|
||||
if (log_level & VIDEO_LOG)
|
||||
rx_pr("%s mix size:%d\n", __func__,
|
||||
(cur_size + addition_size));
|
||||
/*add addition block property to local edid*/
|
||||
rx_mix_block(cur_data, addition);
|
||||
addition_size = (*cur_data & 0x1f) + 1;
|
||||
} else
|
||||
return;
|
||||
if (log_level & VIDEO_LOG)
|
||||
rx_pr(
|
||||
"start_addr: %#x,cur_size: %d,addition_size: %d\n",
|
||||
start_addr, cur_size, addition_size);
|
||||
|
||||
/*set the block value to edid_temp*/
|
||||
start_addr_temp = rx_get_ceadata_offset(buffer, addition);
|
||||
temp_len = ((buffer[start_addr_temp] & 0x1f) + 1);
|
||||
/*check the free size is enough for merged block*/
|
||||
free_size = rx_edid_free_size(buffer, EDID_SIZE);
|
||||
if (log_level & VIDEO_LOG)
|
||||
rx_pr("%s free_size:%d\n", __func__, free_size);
|
||||
if ((free_size < (addition_size - temp_len)) ||
|
||||
(free_size <= 0))
|
||||
return;
|
||||
if (log_level & VIDEO_LOG)
|
||||
rx_pr("edid_temp start: %#x, len: %d\n",
|
||||
start_addr_temp, temp_len);
|
||||
/*move data behind current data if need*/
|
||||
if (temp_len < addition_size) {
|
||||
for (i = 0; i < EDID_SIZE - start_addr_temp -
|
||||
addition_size; i++) {
|
||||
buffer[255 - i] =
|
||||
buffer[255 - (addition_size - temp_len)
|
||||
- i];
|
||||
}
|
||||
} else if (temp_len > addition_size) {
|
||||
for (i = 0; i < EDID_SIZE - start_addr_temp -
|
||||
temp_len; i++) {
|
||||
buffer[start_addr_temp + i + addition_size]
|
||||
= buffer[start_addr_temp + i + temp_len];
|
||||
}
|
||||
}
|
||||
/*check detail description offset if needs modify*/
|
||||
if (start_addr_temp < buffer[EDID_BLOCK1_OFFSET +
|
||||
EDID_DESCRIP_OFFSET] + EDID_BLOCK1_OFFSET)
|
||||
buffer[EDID_BLOCK1_OFFSET + EDID_DESCRIP_OFFSET]
|
||||
+= (addition_size - temp_len);
|
||||
/*copy current edid data*/
|
||||
memcpy(buffer + start_addr_temp, cur_data,
|
||||
addition_size);
|
||||
}
|
||||
}
|
||||
|
||||
void rx_edid_update_audio_info(unsigned char *p_edid,
|
||||
unsigned int len)
|
||||
{
|
||||
if (p_edid == NULL)
|
||||
return;
|
||||
rx_modify_edid(p_edid, len, rx_get_receiver_edid());
|
||||
}
|
||||
|
||||
unsigned int rx_edid_cal_phy_addr(
|
||||
u_int brepeat,
|
||||
u_int up_addr,
|
||||
|
||||
@@ -622,4 +622,8 @@ 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 rx_edid_parse_print(struct edid_info_s *edid_info);
|
||||
void rx_modify_edid(unsigned char *buffer,
|
||||
int len, unsigned char *addition);
|
||||
void rx_edid_update_audio_info(unsigned char *p_edid,
|
||||
unsigned int len);
|
||||
#endif
|
||||
|
||||
@@ -262,6 +262,7 @@ unsigned int hdmirx_rd_top(unsigned int addr)
|
||||
ulong flags;
|
||||
int data;
|
||||
unsigned int dev_offset = 0;
|
||||
|
||||
spin_lock_irqsave(®_rw_lock, flags);
|
||||
wr_reg(MAP_ADDR_MODULE_TOP, hdmirx_addr_port | dev_offset, addr);
|
||||
wr_reg(MAP_ADDR_MODULE_TOP, hdmirx_addr_port | dev_offset, addr);
|
||||
@@ -562,6 +563,26 @@ void hdmirx_wr_ctl_port(unsigned int offset, unsigned int data)
|
||||
spin_unlock_irqrestore(®_rw_lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* hdmirx_top_sw_reset
|
||||
*/
|
||||
void hdmirx_top_sw_reset(void)
|
||||
{
|
||||
ulong flags;
|
||||
unsigned long dev_offset = 0;
|
||||
|
||||
spin_lock_irqsave(®_rw_lock, flags);
|
||||
wr_reg(MAP_ADDR_MODULE_TOP,
|
||||
hdmirx_addr_port | dev_offset, TOP_SW_RESET);
|
||||
wr_reg(MAP_ADDR_MODULE_TOP,
|
||||
hdmirx_data_port | dev_offset, 1);
|
||||
udelay(1);
|
||||
wr_reg(MAP_ADDR_MODULE_TOP,
|
||||
hdmirx_addr_port | dev_offset, TOP_SW_RESET);
|
||||
wr_reg(MAP_ADDR_MODULE_TOP, hdmirx_data_port | dev_offset, 0);
|
||||
spin_unlock_irqrestore(®_rw_lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* rx_irq_en - hdmirx controller irq config
|
||||
* @enable - irq set or clear
|
||||
@@ -1172,6 +1193,9 @@ void control_reset(void)
|
||||
{
|
||||
unsigned long data32;
|
||||
|
||||
/* disable functional modules */
|
||||
hdmirx_top_sw_reset();
|
||||
|
||||
/* Enable functional modules */
|
||||
data32 = 0;
|
||||
data32 |= 1 << 5; /* [5] cec_enable */
|
||||
@@ -1746,6 +1770,7 @@ void hdmirx_hw_config(void)
|
||||
DWC_init();
|
||||
hdmirx_irq_hdcp_enable(true);
|
||||
hdmirx_phy_init();
|
||||
hdmirx_wr_top(TOP_INTR_MASKN, top_intr_maskn_value);
|
||||
rx_pr("%s %d Done!\n", __func__, rx.port);
|
||||
}
|
||||
|
||||
@@ -1853,6 +1878,7 @@ bool is_aud_pll_error(void)
|
||||
void rx_aud_pll_ctl(bool en)
|
||||
{
|
||||
int tmp = 0;
|
||||
|
||||
if (en) {
|
||||
tmp = hdmirx_rd_phy(PHY_MAINFSM_STATUS1);
|
||||
wr_reg_hhi(HHI_AUD_PLL_CNTL, 0x20000000);
|
||||
@@ -2081,6 +2107,7 @@ unsigned int hdmirx_get_clock(int index)
|
||||
unsigned int hdmirx_get_tmds_clock(void)
|
||||
{
|
||||
uint32_t clk = clk_util_clk_msr(25);
|
||||
|
||||
if (clk == 0) {
|
||||
clk = hdmirx_rd_dwc(DWC_HDMI_CKM_RESULT) & 0xffff;
|
||||
clk = clk * 158000 / 4095 * 1000;
|
||||
|
||||
@@ -184,235 +184,11 @@ void rx_check_repeat(void)
|
||||
/*}*/
|
||||
}
|
||||
|
||||
int rx_get_tag_code(uint8_t *edid_data)
|
||||
unsigned char *rx_get_receiver_edid(void)
|
||||
{
|
||||
int tag_code;
|
||||
|
||||
if ((*edid_data >> 5) != 7)
|
||||
tag_code = (*edid_data >> 5);
|
||||
else
|
||||
tag_code = (7 << 8) | *(edid_data + 1);/*extern tag*/
|
||||
|
||||
return tag_code;
|
||||
return receive_edid;
|
||||
}
|
||||
|
||||
int rx_get_ceadata_offset(uint8_t *cur_edid, uint8_t *addition)
|
||||
{
|
||||
int i;
|
||||
int type;
|
||||
|
||||
if ((cur_edid == NULL) || (addition == NULL))
|
||||
return 0;
|
||||
|
||||
type = rx_get_tag_code(addition);
|
||||
i = EDID_DEFAULT_START;/*block check start index*/
|
||||
while (i < 255) {
|
||||
if (type == rx_get_tag_code(cur_edid + i))
|
||||
return i;
|
||||
i += (1 + (*(cur_edid + i) & 0x1f));
|
||||
}
|
||||
if (log_level & VIDEO_LOG)
|
||||
rx_pr("type: %#x, start addr: %#x\n", type, i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rx_mix_edid_audio(uint8_t *cur_data, uint8_t *addition)
|
||||
{
|
||||
struct edid_audio_block_t *ori_data;
|
||||
struct edid_audio_block_t *add_data;
|
||||
unsigned char ori_len, add_len;
|
||||
int i, j;
|
||||
|
||||
if ((cur_data == 0) || (addition == 0) ||
|
||||
(*cur_data >> 5) != (*addition >> 5))
|
||||
return;
|
||||
|
||||
ori_data = (struct edid_audio_block_t *)(cur_data + 1);
|
||||
add_data = (struct edid_audio_block_t *)(addition + 1);
|
||||
ori_len = (*cur_data & 0x1f)/FORMAT_SIZE;
|
||||
add_len = (*addition & 0x1f)/FORMAT_SIZE;
|
||||
|
||||
for (i = 0; i < add_len; i++) {
|
||||
if (log_level & VIDEO_LOG)
|
||||
rx_pr("mix audio format:%d\n", add_data[i].format_code);
|
||||
/*only support lpcm dts dd+*/
|
||||
if (!is_audio_support(add_data[i].format_code))
|
||||
continue;
|
||||
/*mix audio data*/
|
||||
for (j = 0; j < ori_len; j++) {
|
||||
if (ori_data[j].format_code ==
|
||||
add_data[i].format_code) {
|
||||
if (log_level & VIDEO_LOG)
|
||||
rx_pr("mix audio mix format:%d\n",
|
||||
add_data[i].format_code);
|
||||
/*choose channel is lager*/
|
||||
ori_data[j].max_channel =
|
||||
((ori_data[j].max_channel >
|
||||
add_data[i].max_channel) ?
|
||||
ori_data[j].max_channel :
|
||||
add_data[i].max_channel);
|
||||
/*mix sample freqence*/
|
||||
*(((unsigned char *)&ori_data[j]) + 1) =
|
||||
*(((unsigned char *)&ori_data[j]) + 1) |
|
||||
*(((unsigned char *)&add_data[i]) + 1);
|
||||
/*mix bit rate*/
|
||||
if (add_data[i].format_code ==
|
||||
AUDIO_FORMAT_LPCM)
|
||||
*(((unsigned char *)&ori_data[j]) + 2) =
|
||||
*(((unsigned char *)&ori_data[j]) + 2) |
|
||||
*(((unsigned char *)&add_data[i]) + 2);
|
||||
else
|
||||
ori_data[j].bit_rate.others =
|
||||
add_data[i].bit_rate.others;
|
||||
} else {
|
||||
if (j == (ori_len - 1)) {
|
||||
if (log_level & VIDEO_LOG)
|
||||
rx_pr("mix audio add new format: %d\n",
|
||||
add_data[i].format_code);
|
||||
if (((*cur_data & 0x1f) + FORMAT_SIZE)
|
||||
<= 0x1f) {
|
||||
memcpy(cur_data +
|
||||
(*cur_data & 0x1f) + 1,
|
||||
&add_data[i], FORMAT_SIZE);
|
||||
*cur_data += FORMAT_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void rx_mix_edid_hdr(uint8_t *cur_data, uint8_t *addition)
|
||||
{
|
||||
struct edid_hdr_block_t *cur_block;
|
||||
struct edid_hdr_block_t *add_block;
|
||||
|
||||
if ((cur_data == 0) || (addition == 0) ||
|
||||
(*cur_data >> 5) != (*addition >> 5))
|
||||
return;
|
||||
|
||||
cur_block = (struct edid_hdr_block_t *)(cur_data + 1);
|
||||
add_block = (struct edid_hdr_block_t *)(addition + 1);
|
||||
if (add_block->max_lumi | add_block->avg_lumi |
|
||||
add_block->min_lumi) {
|
||||
cur_block->max_lumi = add_block->max_lumi;
|
||||
cur_block->avg_lumi = add_block->avg_lumi;
|
||||
cur_block->min_lumi = add_block->min_lumi;
|
||||
if ((*cur_data & 0x1f) < (*addition & 0x1f))
|
||||
*cur_data = *addition;
|
||||
}
|
||||
}
|
||||
|
||||
void rx_mix_block(uint8_t *cur_data, uint8_t *addition)
|
||||
{
|
||||
int tag_code;
|
||||
|
||||
if ((cur_data == 0) || (addition == 0) ||
|
||||
(*cur_data >> 5) != (*addition >> 5))
|
||||
return;
|
||||
if (log_level & VIDEO_LOG)
|
||||
rx_pr("before type:%d - %d,len:%d - %d\n",
|
||||
(*cur_data >> 5), (*addition >> 5),
|
||||
(*cur_data & 0x1f), (*addition & 0x1f));
|
||||
|
||||
tag_code = rx_get_tag_code(cur_data);
|
||||
|
||||
switch (tag_code) {
|
||||
case EDID_TAG_AUDIO:
|
||||
rx_mix_edid_audio(cur_data, addition);
|
||||
break;
|
||||
|
||||
case EDID_TAG_HDR:
|
||||
rx_mix_edid_hdr(cur_data, addition);
|
||||
break;
|
||||
}
|
||||
if (log_level & VIDEO_LOG)
|
||||
rx_pr("end type:%d - %d,len:%d - %d\n",
|
||||
(*cur_data >> 5), (*addition >> 5),
|
||||
(*cur_data & 0x1f), (*addition & 0x1f));
|
||||
}
|
||||
|
||||
void rx_modify_edid(unsigned char *buffer,
|
||||
int len, unsigned char *addition)
|
||||
{
|
||||
int start_addr = 0;/*the addr in edid need modify*/
|
||||
int start_addr_temp = 0;/*edid_temp start addr*/
|
||||
int temp_len = 0;
|
||||
unsigned char *cur_data = NULL;
|
||||
int addition_size = 0;
|
||||
int cur_size = 0;
|
||||
int i;
|
||||
|
||||
if ((len <= 255) || (buffer == 0) || (addition == 0))
|
||||
return;
|
||||
|
||||
/*get the mix block value*/
|
||||
if (*addition & 0x1f) {
|
||||
/*get addition block index in local edid*/
|
||||
start_addr = rx_get_ceadata_offset(buffer, addition);
|
||||
if (start_addr > EDID_DEFAULT_START) {
|
||||
cur_size = (*(buffer + start_addr) & 0x1f) + 1;
|
||||
addition_size = (*addition & 0x1f) + 1;
|
||||
cur_data = kmalloc(
|
||||
addition_size + cur_size, GFP_KERNEL);
|
||||
if (!cur_data) {
|
||||
rx_pr("allocate cur_data memory failed\n");
|
||||
return;
|
||||
}
|
||||
memcpy(cur_data, buffer + start_addr, cur_size);
|
||||
/*add addition block property to local edid*/
|
||||
rx_mix_block(cur_data, addition);
|
||||
addition_size = (*cur_data & 0x1f) + 1;
|
||||
} else
|
||||
return;
|
||||
if (log_level & VIDEO_LOG)
|
||||
rx_pr(
|
||||
"start_addr: %#x,cur_size: %d,addition_size: %d\n",
|
||||
start_addr, cur_size, addition_size);
|
||||
|
||||
/*set the block value to edid_temp*/
|
||||
start_addr_temp = rx_get_ceadata_offset(buffer, addition);
|
||||
temp_len = ((buffer[start_addr_temp] & 0x1f) + 1);
|
||||
if (log_level & VIDEO_LOG)
|
||||
rx_pr("edid_temp start: %#x, len: %d\n",
|
||||
start_addr_temp, temp_len);
|
||||
/*move data behind current data if need*/
|
||||
if (temp_len < addition_size) {
|
||||
for (i = 0; i < EDID_SIZE - start_addr_temp -
|
||||
addition_size; i++) {
|
||||
buffer[255 - i] =
|
||||
buffer[255 - (addition_size - temp_len)
|
||||
- i];
|
||||
}
|
||||
} else if (temp_len > addition_size) {
|
||||
for (i = 0; i < EDID_SIZE - start_addr_temp -
|
||||
temp_len; i++) {
|
||||
buffer[start_addr_temp + i + addition_size]
|
||||
= buffer[start_addr_temp + i + temp_len];
|
||||
}
|
||||
}
|
||||
/*check detail description offset if needs modify*/
|
||||
if (start_addr_temp < buffer[EDID_BLOCK1_OFFSET +
|
||||
EDID_DESCRIP_OFFSET] + EDID_BLOCK1_OFFSET)
|
||||
buffer[EDID_BLOCK1_OFFSET + EDID_DESCRIP_OFFSET]
|
||||
+= (addition_size - temp_len);
|
||||
/*copy current edid data*/
|
||||
memcpy(buffer + start_addr_temp, cur_data,
|
||||
addition_size);
|
||||
}
|
||||
kfree(cur_data);
|
||||
}
|
||||
|
||||
void rx_edid_update_audio_info(unsigned char *p_edid,
|
||||
unsigned int len)
|
||||
{
|
||||
if (p_edid == NULL)
|
||||
return;
|
||||
rx_modify_edid(p_edid, len, receive_edid);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int rx_set_receiver_edid(unsigned char *data, int len)
|
||||
{
|
||||
if ((data == NULL) || (len == 0) || (len > MAX_RECEIVE_EDID))
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#define MAX_REPEAT_COUNT 127
|
||||
#define MAX_REPEAT_DEPTH 7
|
||||
#define MAX_KSV_LIST_SIZE (MAX_KSV_SIZE*MAX_REPEAT_COUNT)
|
||||
#define DETAILED_TIMING_LEN 18
|
||||
/*size of one format in edid*/
|
||||
#define FORMAT_SIZE sizeof(struct edid_audio_block_t)
|
||||
#define EDID_DEFAULT_START 132
|
||||
@@ -56,15 +57,11 @@ extern bool downstream_rp_en;
|
||||
|
||||
void rx_set_repeater_support(bool enable);
|
||||
extern int rx_set_receiver_edid(unsigned char *data, int len);
|
||||
extern void rx_modify_edid(unsigned char *buffer,
|
||||
int len, unsigned char *addition);
|
||||
extern void rx_start_repeater_auth(void);
|
||||
extern void rx_edid_update_audio_info(unsigned char *p_edid,
|
||||
unsigned int len);
|
||||
extern void rx_set_repeat_signal(bool repeat);
|
||||
extern bool rx_set_repeat_aksv(unsigned char *data, int len, int depth,
|
||||
bool dev_exceed, bool cascade_exceed);
|
||||
|
||||
extern unsigned char *rx_get_receiver_edid(void);
|
||||
extern void repeater_dwork_handle(struct work_struct *work);
|
||||
bool rx_set_receive_hdcp(unsigned char *data,
|
||||
int len, int depth, bool cas_exceed, bool devs_exceed);
|
||||
|
||||
@@ -1312,6 +1312,7 @@ void fsm_restart(void)
|
||||
rx_esm_tmdsclk_en(false);
|
||||
esm_set_stable(false);
|
||||
}
|
||||
hdmirx_hw_config();
|
||||
set_scdc_cfg(1, 0);
|
||||
vic_check_en = true;
|
||||
dvi_check_en = true;
|
||||
@@ -1967,6 +1968,7 @@ void rx_main_state_machine(void)
|
||||
case FSM_5V_LOST:
|
||||
if (rx.cur_5v_sts)
|
||||
rx.state = FSM_INIT;
|
||||
fsm_restart();
|
||||
break;
|
||||
case FSM_HPD_LOW:
|
||||
rx_set_hpd(0);
|
||||
|
||||
@@ -18,17 +18,6 @@
|
||||
#ifndef HDMI_RX_WRAPPER_H_
|
||||
#define HDMI_RX_WRAPPER_H_
|
||||
|
||||
|
||||
#define LOG_EN 0x01
|
||||
#define VIDEO_LOG 0x02
|
||||
#define AUDIO_LOG 0x04
|
||||
#define HDCP_LOG 0x08
|
||||
#define PACKET_LOG 0x10
|
||||
#define EQ_LOG 0x20
|
||||
#define REG_LOG 0x40
|
||||
#define ERR_LOG 0x80
|
||||
#define VSI_LOG 0x800
|
||||
|
||||
/* stable_check_lvl */
|
||||
#define HACTIVE_EN 0x01
|
||||
#define VACTIVE_EN 0x02
|
||||
|
||||
Reference in New Issue
Block a user