mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
hdmitx: add auto low latency mode(ALLM) [1/1]
PD#SWPL-4705 Problem: Lack ALLM function Solution: Add ALLM function Verify: GXL/P212 If Rx supports ALLM, then echo 1 > /sys/class/amhdmitx/amhdmitx0/allm_mode otherwise it will set failed, cat allm_mode and will get 0. Change-Id: I00233e5a5aac133b405590e7df78c7c4805ed0ef Signed-off-by: Zongdong Jiao <zongdong.jiao@amlogic.com>
This commit is contained in:
@@ -2164,3 +2164,22 @@ unsigned int hdmi_get_csc_coef(
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool is_hdmi14_4k(enum hdmi_vic vic)
|
||||
{
|
||||
bool ret = 0;
|
||||
|
||||
switch (vic) {
|
||||
case HDMI_3840x2160p24_16x9:
|
||||
case HDMI_3840x2160p25_16x9:
|
||||
case HDMI_3840x2160p30_16x9:
|
||||
case HDMI_4096x2160p24_256x135:
|
||||
ret = 1;
|
||||
break;
|
||||
default:
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -319,9 +319,9 @@ int Edid_Parse_check_HDMI_VSDB(struct hdmitx_dev *hdev,
|
||||
if (temp_addr >= VSpecificBoundary)
|
||||
ret = -1;
|
||||
else {
|
||||
if ((buff[BlockAddr + 1] != 0x03) ||
|
||||
(buff[BlockAddr + 2] != 0x0C) ||
|
||||
(buff[BlockAddr + 3] != 0x0))
|
||||
if ((buff[BlockAddr + 1] != GET_OUI_BYTE0(HDMI_IEEE_OUI)) ||
|
||||
(buff[BlockAddr + 2] != GET_OUI_BYTE1(HDMI_IEEE_OUI)) ||
|
||||
(buff[BlockAddr + 3] != GET_OUI_BYTE2(HDMI_IEEE_OUI)))
|
||||
ret = -1;
|
||||
}
|
||||
return ret;
|
||||
@@ -1501,7 +1501,7 @@ static int hdmitx_edid_block_parse(struct hdmitx_dev *hdmitx_device,
|
||||
if ((BlockBuf[offset] == 0x03) &&
|
||||
(BlockBuf[offset+1] == 0x0c) &&
|
||||
(BlockBuf[offset+2] == 0x00)) {
|
||||
pRXCap->IEEEOUI = 0x000c03;
|
||||
pRXCap->IEEEOUI = HDMI_IEEE_OUI;
|
||||
pRXCap->ColorDeepSupport =
|
||||
(count > 5) ? BlockBuf[offset+5] : 0;
|
||||
set_vsdb_dc_cap(pRXCap);
|
||||
@@ -1548,7 +1548,7 @@ static int hdmitx_edid_block_parse(struct hdmitx_dev *hdmitx_device,
|
||||
} else if ((BlockBuf[offset] == 0xd8) &&
|
||||
(BlockBuf[offset+1] == 0x5d) &&
|
||||
(BlockBuf[offset+2] == 0xc4)) {
|
||||
pRXCap->HF_IEEEOUI = 0xd85dc4;
|
||||
pRXCap->HF_IEEEOUI = HF_IEEE_OUI;
|
||||
pRXCap->Max_TMDS_Clock2 = BlockBuf[offset+4];
|
||||
pRXCap->scdc_present =
|
||||
!!(BlockBuf[offset+5] & (1 << 7));
|
||||
@@ -1558,6 +1558,11 @@ static int hdmitx_edid_block_parse(struct hdmitx_dev *hdmitx_device,
|
||||
!!(BlockBuf[offset+5] & (1 << 3));
|
||||
set_vsdb_dc_420_cap(&hdmitx_device->RXCap,
|
||||
&BlockBuf[offset]);
|
||||
if (count > 7) {
|
||||
unsigned char b7 = BlockBuf[offset+7];
|
||||
|
||||
pRXCap->allm = !!(b7 & (1 << 1));
|
||||
}
|
||||
}
|
||||
|
||||
offset += count; /* ignore the remaind. */
|
||||
@@ -2100,9 +2105,9 @@ int hdmitx_edid_parse(struct hdmitx_dev *hdmitx_device)
|
||||
if ((CheckSum & 0xff) == 0)
|
||||
hdmitx_device->RXCap.IEEEOUI = 0;
|
||||
else
|
||||
hdmitx_device->RXCap.IEEEOUI = 0x0c03;
|
||||
hdmitx_device->RXCap.IEEEOUI = HDMI_IEEE_OUI;
|
||||
if (zero_numbers > 120)
|
||||
hdmitx_device->RXCap.IEEEOUI = 0x0c03;
|
||||
hdmitx_device->RXCap.IEEEOUI = HDMI_IEEE_OUI;
|
||||
|
||||
return 0; /* do nothing. */
|
||||
}
|
||||
@@ -2168,14 +2173,14 @@ int hdmitx_edid_parse(struct hdmitx_dev *hdmitx_device)
|
||||
}
|
||||
|
||||
if (hdmitx_edid_search_IEEEOUI(&EDID_buf[128])) {
|
||||
pRXCap->IEEEOUI = 0x0c03;
|
||||
pRXCap->IEEEOUI = HDMI_IEEE_OUI;
|
||||
pr_info(EDID "find IEEEOUT\n");
|
||||
} else {
|
||||
pRXCap->IEEEOUI = 0x0;
|
||||
pr_info(EDID "not find IEEEOUT\n");
|
||||
}
|
||||
|
||||
if ((pRXCap->IEEEOUI != 0x0c03) || (pRXCap->IEEEOUI == 0x0) ||
|
||||
if ((pRXCap->IEEEOUI != HDMI_IEEE_OUI) || (pRXCap->IEEEOUI == 0x0) ||
|
||||
(pRXCap->VIC_count == 0))
|
||||
hdmitx_edid_set_default_vic(hdmitx_device);
|
||||
|
||||
@@ -2186,10 +2191,10 @@ int hdmitx_edid_parse(struct hdmitx_dev *hdmitx_device)
|
||||
pRXCap->IEEEOUI = 0x0;
|
||||
pr_info(EDID "sink is DVI device\n");
|
||||
} else
|
||||
pRXCap->IEEEOUI = 0x0c03;
|
||||
pRXCap->IEEEOUI = HDMI_IEEE_OUI;
|
||||
|
||||
if (edid_zero_data(EDID_buf))
|
||||
pRXCap->IEEEOUI = 0x0c03;
|
||||
pRXCap->IEEEOUI = HDMI_IEEE_OUI;
|
||||
|
||||
if ((!pRXCap->AUD_count) && (!pRXCap->IEEEOUI))
|
||||
hdmitx_edid_set_default_aud(hdmitx_device);
|
||||
@@ -2201,7 +2206,7 @@ int hdmitx_edid_parse(struct hdmitx_dev *hdmitx_device)
|
||||
hdmitx_device->tmp_buf[i] = 0;
|
||||
|
||||
if (!hdmitx_edid_check_valid_blocks(&EDID_buf[0])) {
|
||||
pRXCap->IEEEOUI = 0x0c03;
|
||||
pRXCap->IEEEOUI = HDMI_IEEE_OUI;
|
||||
pr_info(EDID "Invalid edid, consider RX as HDMI device\n");
|
||||
}
|
||||
/* update RX HDR information */
|
||||
@@ -2358,7 +2363,7 @@ bool hdmitx_edid_check_valid_mode(struct hdmitx_dev *hdev,
|
||||
pRXCap = &(hdev->RXCap);
|
||||
|
||||
/* DVI case, only 8bit */
|
||||
if (pRXCap->IEEEOUI != 0x0c03) {
|
||||
if (pRXCap->IEEEOUI != HDMI_IEEE_OUI) {
|
||||
if (para->cd != COLORDEPTH_24B)
|
||||
return 0;
|
||||
}
|
||||
@@ -2519,7 +2524,7 @@ void hdmitx_edid_clear(struct hdmitx_dev *hdmitx_device)
|
||||
/* Note: in most cases, we think that rx is tv and the default
|
||||
* IEEEOUI is HDMI Identifier
|
||||
*/
|
||||
pRXCap->IEEEOUI = 0x000c03;
|
||||
pRXCap->IEEEOUI = HDMI_IEEE_OUI;
|
||||
|
||||
hdmitx_device->vic_count = 0;
|
||||
hdmitx_device->hdmi_info.vsdb_phy_addr.a = 0;
|
||||
@@ -2711,6 +2716,10 @@ int hdmitx_edid_dump(struct hdmitx_dev *hdmitx_device, char *buffer,
|
||||
"MaxTMDSClock2 %d MHz\n", pRXCap->Max_TMDS_Clock2 * 5);
|
||||
}
|
||||
|
||||
if (pRXCap->allm)
|
||||
pos += snprintf(buffer+pos, buffer_len-pos, "ALLM: %x\n",
|
||||
pRXCap->allm);
|
||||
|
||||
pos += snprintf(buffer+pos, buffer_len-pos, "vLatency: ");
|
||||
if (pRXCap->vLatency == LATENCY_INVALID_UNKNOWN)
|
||||
pos += snprintf(buffer+pos, buffer_len-pos,
|
||||
|
||||
@@ -2504,6 +2504,77 @@ static ssize_t store_valid_mode(struct device *dev,
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t show_allm_mode(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
int pos = 0;
|
||||
struct hdmitx_dev *hdev = &hdmitx_device;
|
||||
struct rx_cap *pRXCap = &(hdmitx_device.RXCap);
|
||||
|
||||
if (!pRXCap->allm) { /* Rx not support ALLM */
|
||||
pos += snprintf(buf + pos, PAGE_SIZE, "0\n\r");
|
||||
return pos;
|
||||
}
|
||||
|
||||
if (hdev->allm_mode == 1)
|
||||
pos += snprintf(buf + pos, PAGE_SIZE, "game\n\r");
|
||||
else if (hdev->allm_mode == 2)
|
||||
pos += snprintf(buf + pos, PAGE_SIZE, "graphics\n\r");
|
||||
else if (hdev->allm_mode == 3)
|
||||
pos += snprintf(buf + pos, PAGE_SIZE, "photo\n\r");
|
||||
else if (hdev->allm_mode == 4)
|
||||
pos += snprintf(buf + pos, PAGE_SIZE, "cinema\n\r");
|
||||
else
|
||||
pos += snprintf(buf + pos, PAGE_SIZE, "0\n\r");
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
static ssize_t store_allm_mode(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
struct hdmitx_dev *hdev = &hdmitx_device;
|
||||
struct rx_cap *pRXCap = &hdev->RXCap;
|
||||
|
||||
pr_info("hdmitx: store allm_mode as %s\n", buf);
|
||||
|
||||
if (!pRXCap->allm) /* Rx not support ALLM */
|
||||
return count;
|
||||
|
||||
#define CMP_STR(str) (strncmp(buf, str, strlen(str)) == 0)
|
||||
if (CMP_STR("0")) {
|
||||
// disable ALLM
|
||||
hdev->allm_mode = 0;
|
||||
hdev->HWOp.CntlConfig(hdev, CONF_ALLM_MODE, CLEAR_ALLM_MODE);
|
||||
hdmitx_construct_vsif(hdev, VT_ALLM, 0, NULL);
|
||||
if (is_hdmi14_4k(hdev->cur_VIC))
|
||||
hdmitx_construct_vsif(hdev, VT_HDMI14_4K, 1, NULL);
|
||||
return count;
|
||||
}
|
||||
if (CMP_STR("1") || CMP_STR("game") || CMP_STR("graphics")
|
||||
|| CMP_STR("photo") || CMP_STR("cinema")) {
|
||||
hdmitx_construct_vsif(hdev, VT_ALLM, 1, NULL);
|
||||
}
|
||||
if (CMP_STR("1") || CMP_STR("game")) {
|
||||
hdev->allm_mode = 1;
|
||||
// enable the default GAME ALLM
|
||||
hdev->HWOp.CntlConfig(hdev, CONF_ALLM_MODE, SET_ALLM_GAME);
|
||||
}
|
||||
if (CMP_STR("graphics")) {
|
||||
hdev->allm_mode = 2;
|
||||
hdev->HWOp.CntlConfig(hdev, CONF_ALLM_MODE, SET_ALLM_GRAPHICS);
|
||||
}
|
||||
if (CMP_STR("photo")) {
|
||||
hdev->allm_mode = 3;
|
||||
hdev->HWOp.CntlConfig(hdev, CONF_ALLM_MODE, SET_ALLM_PHOTO);
|
||||
}
|
||||
if (CMP_STR("cinema")) {
|
||||
hdev->allm_mode = 4;
|
||||
hdev->HWOp.CntlConfig(hdev, CONF_ALLM_MODE, SET_ALLM_CINEMA);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/**/
|
||||
static ssize_t show_hdr_cap(struct device *dev,
|
||||
@@ -3389,6 +3460,7 @@ static DEVICE_ATTR(hdr_cap, 0444, show_hdr_cap, NULL);
|
||||
static DEVICE_ATTR(dv_cap, 0444, show_dv_cap, NULL);
|
||||
static DEVICE_ATTR(dc_cap, 0444, show_dc_cap, NULL);
|
||||
static DEVICE_ATTR(valid_mode, 0664, show_valid_mode, store_valid_mode);
|
||||
static DEVICE_ATTR(allm_mode, 0664, show_allm_mode, store_allm_mode);
|
||||
static DEVICE_ATTR(aud_ch, 0664, show_aud_ch, store_aud_ch);
|
||||
static DEVICE_ATTR(avmute, 0664, show_avmute, store_avmute);
|
||||
static DEVICE_ATTR(swap, 0644, show_swap, store_swap);
|
||||
@@ -3756,7 +3828,7 @@ static void hdmitx_hpd_plugin_handler(struct work_struct *work)
|
||||
rx_repeat_hpd_state(1);
|
||||
hdmitx_get_edid(hdev);
|
||||
hdmi_physcial_size_update(hdev);
|
||||
if (hdev->RXCap.IEEEOUI != 0x000c03)
|
||||
if (hdev->RXCap.IEEEOUI != HDMI_IEEE_OUI)
|
||||
hdev->HWOp.CntlConfig(hdev,
|
||||
CONF_HDMI_DVI_MODE, DVI_MODE);
|
||||
else
|
||||
@@ -4508,6 +4580,7 @@ static int amhdmitx_probe(struct platform_device *pdev)
|
||||
ret = device_create_file(dev, &dev_attr_support_3d);
|
||||
ret = device_create_file(dev, &dev_attr_dc_cap);
|
||||
ret = device_create_file(dev, &dev_attr_valid_mode);
|
||||
ret = device_create_file(dev, &dev_attr_allm_mode);
|
||||
|
||||
#ifdef CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND
|
||||
register_early_suspend(&hdmitx_early_suspend_handler);
|
||||
@@ -4577,6 +4650,7 @@ static int amhdmitx_remove(struct platform_device *pdev)
|
||||
device_remove_file(dev, &dev_attr_dv_cap);
|
||||
device_remove_file(dev, &dev_attr_dc_cap);
|
||||
device_remove_file(dev, &dev_attr_valid_mode);
|
||||
device_remove_file(dev, &dev_attr_allm_mode);
|
||||
device_remove_file(dev, &dev_attr_hpd_state);
|
||||
device_remove_file(dev, &dev_attr_rhpd_state);
|
||||
device_remove_file(dev, &dev_attr_max_exceed);
|
||||
|
||||
@@ -552,12 +552,12 @@ static void hdmi_tx_construct_avi_packet(
|
||||
*************************************/
|
||||
|
||||
/*
|
||||
* HDMI Identifier = 0x000c03
|
||||
* HDMI Identifier = HDMI_IEEE_OUI 0x000c03
|
||||
* If not, treated as a DVI Device
|
||||
*/
|
||||
static int is_dvi_device(struct rx_cap *pRXCap)
|
||||
{
|
||||
if (pRXCap->IEEEOUI != 0x000c03)
|
||||
if (pRXCap->IEEEOUI != HDMI_IEEE_OUI)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
@@ -645,6 +645,29 @@ int hdmitx_set_display(struct hdmitx_dev *hdev, enum hdmi_vic VideoCode)
|
||||
hdmi_set_vend_spec_infofram(hdev, 0);
|
||||
else
|
||||
;
|
||||
|
||||
switch (hdev->RXCap.allm ? hdev->allm_mode : 0) {
|
||||
case 1: /* game */
|
||||
hdmitx_construct_vsif(hdev, VT_ALLM, 1, NULL);
|
||||
hdev->HWOp.CntlConfig(hdev, CONF_ALLM_MODE,
|
||||
SET_ALLM_GAME);
|
||||
break;
|
||||
case 2: /* graphics */
|
||||
hdev->HWOp.CntlConfig(hdev, CONF_ALLM_MODE,
|
||||
SET_ALLM_GRAPHICS);
|
||||
break;
|
||||
case 3: /* photo */
|
||||
hdev->HWOp.CntlConfig(hdev, CONF_ALLM_MODE,
|
||||
SET_ALLM_PHOTO);
|
||||
break;
|
||||
case 4: /* cinema */
|
||||
hdev->HWOp.CntlConfig(hdev, CONF_ALLM_MODE,
|
||||
SET_ALLM_CINEMA);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
@@ -675,9 +698,9 @@ static void hdmi_set_vend_spec_infofram(struct hdmitx_dev *hdev,
|
||||
|
||||
for (i = 0; i < 0x6; i++)
|
||||
VEN_DB[i] = 0;
|
||||
VEN_DB[0] = 0x03;
|
||||
VEN_DB[1] = 0x0c;
|
||||
VEN_DB[2] = 0x00;
|
||||
VEN_DB[0] = GET_OUI_BYTE0(HDMI_IEEE_OUI);
|
||||
VEN_DB[1] = GET_OUI_BYTE1(HDMI_IEEE_OUI);
|
||||
VEN_DB[2] = GET_OUI_BYTE2(HDMI_IEEE_OUI);
|
||||
VEN_DB[3] = 0x00; /* 4k x 2k Spec P156 */
|
||||
|
||||
if (VideoCode == HDMI_4k2k_30) {
|
||||
@@ -711,9 +734,9 @@ int hdmi_set_3d(struct hdmitx_dev *hdev, int type, unsigned int param)
|
||||
else {
|
||||
for (i = 0; i < 0x6; i++)
|
||||
VEN_DB[i] = 0;
|
||||
VEN_DB[0] = 0x03;
|
||||
VEN_DB[1] = 0x0c;
|
||||
VEN_DB[2] = 0x00;
|
||||
VEN_DB[0] = GET_OUI_BYTE0(HDMI_IEEE_OUI);
|
||||
VEN_DB[1] = GET_OUI_BYTE1(HDMI_IEEE_OUI);
|
||||
VEN_DB[2] = GET_OUI_BYTE2(HDMI_IEEE_OUI);
|
||||
VEN_DB[3] = 0x40;
|
||||
VEN_DB[4] = type<<4;
|
||||
VEN_DB[5] = param<<4;
|
||||
@@ -751,3 +774,74 @@ static void hdmitx_set_spd_info(struct hdmitx_dev *hdev)
|
||||
SPD_DB[24] = 0x1;
|
||||
hdev->HWOp.SetPacket(HDMI_SOURCE_DESCRIPTION, SPD_DB, SPD_HB);
|
||||
}
|
||||
|
||||
static void fill_hdmi4k_vsif_data(enum hdmi_vic vic, unsigned char *DB,
|
||||
unsigned char *HB)
|
||||
{
|
||||
if (!DB || !HB)
|
||||
return;
|
||||
|
||||
if (vic == HDMI_4k2k_30)
|
||||
DB[4] = 0x1;
|
||||
else if (vic == HDMI_4k2k_25)
|
||||
DB[4] = 0x2;
|
||||
else if (vic == HDMI_4k2k_24)
|
||||
DB[4] = 0x3;
|
||||
else if (vic == HDMI_4k2k_smpte_24)
|
||||
DB[4] = 0x4;
|
||||
else
|
||||
return;
|
||||
HB[0] = 0x81;
|
||||
HB[1] = 0x01;
|
||||
HB[2] = 0x5;
|
||||
DB[3] = 0x20;
|
||||
}
|
||||
|
||||
int hdmitx_construct_vsif(struct hdmitx_dev *hdev, enum vsif_type type,
|
||||
int on, void *param)
|
||||
{
|
||||
unsigned char HB[3] = {0x81, 0x1, 0};
|
||||
unsigned char len = 0; /* HB[2] = len */
|
||||
unsigned char DB[27]; /* to be fulfilled */
|
||||
unsigned int ieeeoui = 0;
|
||||
|
||||
if (!hdev || type >= VT_MAX)
|
||||
return 0;
|
||||
memset(DB, 0, sizeof(DB));
|
||||
|
||||
switch (type) {
|
||||
case VT_DEFAULT:
|
||||
break;
|
||||
case VT_HDMI14_4K:
|
||||
ieeeoui = HDMI_IEEE_OUI;
|
||||
len = 5;
|
||||
if (is_hdmi14_4k(hdev->cur_VIC)) {
|
||||
fill_hdmi4k_vsif_data(hdev->cur_VIC, DB, HB);
|
||||
hdmitx_set_avi_vic(0);
|
||||
}
|
||||
break;
|
||||
case VT_ALLM:
|
||||
ieeeoui = HF_IEEE_OUI;
|
||||
len = 5;
|
||||
DB[3] = 0x1; /* Fixed value */
|
||||
if (on) {
|
||||
DB[4] |= 1 << 1; /* set bit1, ALLM_MODE */
|
||||
if (is_hdmi14_4k(hdev->cur_VIC))
|
||||
hdmitx_set_avi_vic(hdev->cur_VIC);
|
||||
} else {
|
||||
DB[4] &= ~(1 << 1); /* clear bit1, ALLM_MODE */
|
||||
/* still send out HS_VSIF, no set AVI.VIC = 0 */
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
HB[2] = len;
|
||||
DB[0] = GET_OUI_BYTE0(ieeeoui);
|
||||
DB[1] = GET_OUI_BYTE1(ieeeoui);
|
||||
DB[2] = GET_OUI_BYTE2(ieeeoui);
|
||||
|
||||
hdev->HWOp.SetDataPacket(HDMI_PACKET_VEND, DB, HB);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -68,6 +68,8 @@ struct ksv_lists_ {
|
||||
static struct ksv_lists_ tmp_ksv_lists;
|
||||
|
||||
static void hdmitx_set_packet(int type, unsigned char *DB, unsigned char *HB);
|
||||
static void hdmitx_set_datapacket(int type, unsigned char *DB,
|
||||
unsigned char *HB);
|
||||
static void hdmitx_setaudioinfoframe(unsigned char *AUD_DB,
|
||||
unsigned char *CHAN_STAT_BUF);
|
||||
static int hdmitx_set_dispmode(struct hdmitx_dev *hdev);
|
||||
@@ -242,6 +244,11 @@ static void config_avmute(unsigned int val)
|
||||
}
|
||||
}
|
||||
|
||||
void hdmitx_set_avi_vic(enum hdmi_vic vic)
|
||||
{
|
||||
hdmitx_wr_reg(HDMITX_DWC_FC_AVIVID, vic);
|
||||
}
|
||||
|
||||
static int read_avmute(void)
|
||||
{
|
||||
int val;
|
||||
@@ -600,6 +607,7 @@ static void hdmi_hwi_init(struct hdmitx_dev *hdev)
|
||||
void HDMITX_Meson_Init(struct hdmitx_dev *hdev)
|
||||
{
|
||||
hdev->HWOp.SetPacket = hdmitx_set_packet;
|
||||
hdev->HWOp.SetDataPacket = hdmitx_set_datapacket;
|
||||
hdev->HWOp.SetAudioInfoFrame = hdmitx_setaudioinfoframe;
|
||||
hdev->HWOp.SetDispMode = hdmitx_set_dispmode;
|
||||
hdev->HWOp.SetAudMode = hdmitx_set_audmode;
|
||||
@@ -2079,6 +2087,40 @@ static void hdmitx_set_packet(int type, unsigned char *DB, unsigned char *HB)
|
||||
}
|
||||
}
|
||||
|
||||
static void hdmitx_set_datapacket(int type, unsigned char *DB,
|
||||
unsigned char *HB)
|
||||
{
|
||||
int i;
|
||||
#if 0
|
||||
pr_info("HB: %02x %02x %02x\nDB:", HB[0], HB[1], HB[2]);
|
||||
for (i = 0; (i < 24) && (i < HB[2]); i++)
|
||||
pr_info(" %02x", DB[i]);
|
||||
pr_info("\n");
|
||||
#endif
|
||||
switch (type) {
|
||||
case HDMI_PACKET_VEND:
|
||||
if ((!DB) || (!HB)) {
|
||||
hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO0, 0, 3, 1);
|
||||
hdmitx_wr_reg(HDMITX_DWC_FC_VSDSIZE, 0x0);
|
||||
return;
|
||||
}
|
||||
hdmitx_wr_reg(HDMITX_DWC_FC_VSDSIZE, HB[2]);
|
||||
hdmitx_wr_reg(HDMITX_DWC_FC_VSDIEEEID0, DB[0]);
|
||||
hdmitx_wr_reg(HDMITX_DWC_FC_VSDIEEEID1, DB[1]);
|
||||
hdmitx_wr_reg(HDMITX_DWC_FC_VSDIEEEID2, DB[2]);
|
||||
for (i = 0; (i < 24) && (i < HB[2]); i++)
|
||||
hdmitx_wr_reg(HDMITX_DWC_FC_VSDPAYLOAD0 + i, DB[3 + i]);
|
||||
/* Enable VSI packet */
|
||||
hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO0, 1, 3, 1);
|
||||
hdmitx_wr_reg(HDMITX_DWC_FC_DATAUTO1, 0);
|
||||
hdmitx_wr_reg(HDMITX_DWC_FC_DATAUTO2, 0x10);
|
||||
hdmitx_set_reg_bits(HDMITX_DWC_FC_PACKET_TX_EN, 1, 4, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void hdmitx_setaudioinfoframe(unsigned char *AUD_DB,
|
||||
unsigned char *CHAN_STAT_BUF)
|
||||
@@ -4681,6 +4723,28 @@ static int hdmitx_cntl_config(struct hdmitx_dev *hdev, unsigned int cmd,
|
||||
case CONF_AVI_YQ01:
|
||||
hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF3, argv, 2, 2);
|
||||
break;
|
||||
case CONF_ALLM_MODE:
|
||||
if (argv == CLEAR_ALLM_MODE) {
|
||||
hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF2, 0, 7, 1);
|
||||
hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF3, 0, 0, 2);
|
||||
break;
|
||||
}
|
||||
if (argv == GET_ALLM_MODE) {
|
||||
if (hdmitx_rd_reg(HDMITX_DWC_FC_AVICONF2) & (1 << 7))
|
||||
ret = hdmitx_rd_reg(HDMITX_DWC_FC_AVICONF3) & 3;
|
||||
else
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
/* set ALLM mode */
|
||||
hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF2, 1, 7, 1);
|
||||
hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF3, argv & 3, 0, 2);
|
||||
if (argv == SET_ALLM_PHOTO) {
|
||||
// TODO
|
||||
// Extended colorimetry field may be
|
||||
// sYcc601, AdobeYcc601 or AdobeRGB
|
||||
}
|
||||
break;
|
||||
case CONF_EMP_NUMBER:
|
||||
hdmitx_set_reg_bits(HDMITX_TOP_EMP_CNTL0, argv, 16, 16);
|
||||
break;
|
||||
|
||||
@@ -30,6 +30,13 @@
|
||||
|
||||
#define HDMITX_VIC_MASK 0xff
|
||||
|
||||
/* Refer to http://standards-oui.ieee.org/oui/oui.txt */
|
||||
#define HDMI_IEEE_OUI 0x000C03
|
||||
#define HF_IEEE_OUI 0xC45DD8
|
||||
#define GET_OUI_BYTE0(oui) (oui & 0xff) /* Little Endian */
|
||||
#define GET_OUI_BYTE1(oui) ((oui >> 8) & 0xff)
|
||||
#define GET_OUI_BYTE2(oui) ((oui >> 16) & 0xff)
|
||||
|
||||
enum hdmi_vic {
|
||||
/* Refer to CEA 861-D */
|
||||
HDMI_Unknown = 0,
|
||||
|
||||
@@ -109,6 +109,11 @@ struct rx_cap {
|
||||
unsigned int dc_30bit_420:1;
|
||||
unsigned int dc_36bit_420:1;
|
||||
unsigned int dc_48bit_420:1;
|
||||
unsigned int max_frl_rate:4;
|
||||
unsigned int fpap_start_loc:1;
|
||||
unsigned int allm:1;
|
||||
unsigned int mdelta:1;
|
||||
unsigned int fva:1;
|
||||
unsigned int hdr_sup_eotf_sdr:1;
|
||||
unsigned int hdr_sup_eotf_hdr:1;
|
||||
unsigned int hdr_sup_eotf_smpte_st_2084:1;
|
||||
@@ -322,6 +327,12 @@ struct hdmitx_dev {
|
||||
struct {
|
||||
void (*SetPacket)(int type, unsigned char *DB,
|
||||
unsigned char *HB);
|
||||
/* In original SetPacket, there are many policys, like
|
||||
* if ((DB[4] >> 4) == T3D_FRAME_PACKING)
|
||||
* Need a only pure data packet to call
|
||||
*/
|
||||
void (*SetDataPacket)(int type, unsigned char *DB,
|
||||
unsigned char *HB);
|
||||
void (*SetAudioInfoFrame)(unsigned char *AUD_DB,
|
||||
unsigned char *CHAN_STAT_BUF);
|
||||
int (*SetDispMode)(struct hdmitx_dev *hdmitx_device);
|
||||
@@ -408,6 +419,8 @@ struct hdmitx_dev {
|
||||
/* 0.1% clock shift, 1080p60hz->59.94hz */
|
||||
unsigned int frac_rate_policy;
|
||||
unsigned int rxsense_policy;
|
||||
/* allm_mode: 1/game, 2/graphcis, 3/photo, 4/cinema */
|
||||
unsigned int allm_mode;
|
||||
unsigned int sspll;
|
||||
/* configure for I2S: 8ch in, 2ch out */
|
||||
/* 0: default setting 1:ch0/1 2:ch2/3 3:ch4/5 4:ch6/7 */
|
||||
@@ -493,6 +506,13 @@ struct hdmitx_dev {
|
||||
#define YCC_RANGE_LIM 0
|
||||
#define YCC_RANGE_FUL 1
|
||||
#define YCC_RANGE_RSVD 2
|
||||
#define CONF_ALLM_MODE (CMD_CONF_OFFSET + 0X2000 + 0x04)
|
||||
#define SET_ALLM_GRAPHICS 0
|
||||
#define SET_ALLM_PHOTO 1
|
||||
#define SET_ALLM_CINEMA 2
|
||||
#define SET_ALLM_GAME 3
|
||||
#define CLEAR_ALLM_MODE 0xf
|
||||
#define GET_ALLM_MODE 0x10
|
||||
#define CONF_VIDEO_MUTE_OP (CMD_CONF_OFFSET + 0x1000 + 0x04)
|
||||
#define VIDEO_MUTE 0x1
|
||||
#define VIDEO_UNMUTE 0x2
|
||||
@@ -595,6 +615,42 @@ extern void hdmitx_edid_buf_compare_print(struct hdmitx_dev *hdmitx_device);
|
||||
|
||||
extern const char *hdmitx_edid_get_native_VIC(struct hdmitx_dev *hdmitx_device);
|
||||
|
||||
/* VSIF: Vendor Specific InfoFrame
|
||||
* It has multiple purposes:
|
||||
* 1. HDMI1.4 4K, HDMI_VIC=1/2/3/4, 2160p30/25/24hz, smpte24hz, AVI.VIC=0
|
||||
* In CTA-861-G, matched with AVI.VIC=95/94/93/98
|
||||
* 2. 3D application, TB/SS/FP
|
||||
* 3. DolbyVision, with Len=0x18
|
||||
* 4. HDR10plus
|
||||
* 5. HDMI20 3D OSD disparity / 3D dual-view / 3D independent view / ALLM
|
||||
* Some functions are exclusive, but some may compound.
|
||||
* Consider various state transitions carefully, such as play 3D under HDMI14
|
||||
* 4K, exit 3D under 4K, play DV under 4K, enable ALLM under 3D dual-view
|
||||
*/
|
||||
enum vsif_type {
|
||||
/* Below 4 functions are exclusive */
|
||||
VT_HDMI14_4K = 1,
|
||||
VT_T3D_VIDEO,
|
||||
VT_DOLBYVISION,
|
||||
VT_HDR10PLUS,
|
||||
/* Maybe compound 3D dualview + ALLM */
|
||||
VT_T3D_OSD_DISPARITY = 0x10,
|
||||
VT_T3D_DUALVIEW,
|
||||
VT_T3D_INDEPENDVEW,
|
||||
VT_ALLM,
|
||||
/* default: if non-HDMI4K, no any vsif; if HDMI4k, = VT_HDMI14_4K */
|
||||
VT_DEFAULT,
|
||||
VT_MAX,
|
||||
};
|
||||
int hdmitx_construct_vsif(struct hdmitx_dev *hdev, enum vsif_type type, int on,
|
||||
void *param);
|
||||
|
||||
/* if vic is 93 ~ 95, or 98 (HDMI14 4K), return 1 */
|
||||
bool is_hdmi14_4k(enum hdmi_vic vic);
|
||||
|
||||
/* set vic to AVI.VIC */
|
||||
void hdmitx_set_avi_vic(enum hdmi_vic vic);
|
||||
|
||||
/*
|
||||
* HDMI Repeater TX I/F
|
||||
* RX downstream Information from rptx to rprx
|
||||
|
||||
Reference in New Issue
Block a user