hdmitx: rewrite edidinfo to vinfo [1/1]

PD#SWPL-14910

Problem:
When HDMI plugin, it will read edid, parse edid, (and here dv mode maybe changed),
notify, etc...

Solution:
rewrite edidinfo to vinfo and update when tx mode is ready

Verify:
G12/U212

Change-Id: I81eb1943f6444fd2c87e0353f6e2782bd9c6c9c1
Signed-off-by: Zongdong Jiao <zongdong.jiao@amlogic.com>
This commit is contained in:
Zongdong Jiao
2019-11-07 20:27:38 +08:00
committed by Luke Go
parent 18100c2b93
commit 4ae16a851e
2 changed files with 65 additions and 72 deletions

View File

@@ -2113,47 +2113,6 @@ static void edid_check_pcm_declare(struct rx_cap *prxcap)
}
}
static void hdrinfo_to_vinfo(struct vinfo_s *info, struct rx_cap *prxcap)
{
unsigned int k, l;
/*static hdr*/
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);
memcpy(info->hdr_info.rawdata, prxcap->hdr_rawdata, 7);
/*dynamic hdr*/
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];
}
}
/*hdr 10+*/
memcpy(&info->hdr_info.hdr10plus_info,
&prxcap->hdr10plus_info, sizeof(struct hdr10_plus_info));
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);
}
static bool is_4k60_supported(struct rx_cap *prxcap)
{
int i = 0;
@@ -2170,16 +2129,6 @@ static bool is_4k60_supported(struct rx_cap *prxcap)
return false;
}
static void rxlatency_to_vinfo(struct vinfo_s *info, struct rx_cap *rx)
{
if (!info || !rx)
return;
info->rx_latency.vLatency = rx->vLatency;
info->rx_latency.aLatency = rx->aLatency;
info->rx_latency.i_vLatency = rx->i_vLatency;
info->rx_latency.i_aLatency = rx->i_aLatency;
}
static void Edid_Descriptor_PMT(struct rx_cap *prxcap,
struct vesa_standard_timing *t,
unsigned char *data)
@@ -2281,7 +2230,6 @@ int hdmitx_edid_parse(struct hdmitx_dev *hdmitx_device)
int idx[4];
struct rx_cap *prxcap = &hdmitx_device->rxcap;
struct dv_info *dv = &hdmitx_device->rxcap.dv_info;
struct vinfo_s *info = NULL;
unsigned int max_tmds_clk = 0;
if (check_dvi_hdmi_edid_valid(hdmitx_device->EDID_buf)) {
@@ -2547,18 +2495,6 @@ int hdmitx_edid_parse(struct hdmitx_dev *hdmitx_device)
prxcap->ieeeoui = HDMI_IEEEOUI;
pr_info(EDID "Invalid edid, consider RX as HDMI device\n");
}
/* update RX HDR information */
info = get_current_vinfo();
if (info) {
/*update hdmi checksum to vout*/
memcpy(info->hdmichecksum, prxcap->chksum, 10);
if (!((strncmp(info->name, "480cvbs", 7) == 0) ||
(strncmp(info->name, "576cvbs", 7) == 0) ||
(strncmp(info->name, "null", 4) == 0))) {
hdrinfo_to_vinfo(info, prxcap);
rxlatency_to_vinfo(info, prxcap);
}
}
/* if sup_2160p60hz of dv is true, check the MAX_TMDS*/
if (dv->sup_2160p60hz) {
if (prxcap->Max_TMDS_Clock2 * 5 < 590) {

View File

@@ -81,6 +81,10 @@ static void hdmitx_set_emp_pkt(unsigned char *data,
static int check_fbc_special(unsigned char *edid_dat);
static struct vinfo_s *hdmitx_get_current_vinfo(void);
static void hdmitx_fmt_attr(struct hdmitx_dev *hdev);
static void clear_rx_vinfo(struct hdmitx_dev *hdev);
static void edidinfo_attach_to_vinfo(struct hdmitx_dev *hdev);
static void edidinfo_detach_to_vinfo(struct hdmitx_dev *hdev);
static DEFINE_MUTEX(setclk_mutex);
static DEFINE_MUTEX(getedid_mutex);
@@ -89,6 +93,9 @@ static struct hdmitx_dev hdmitx_device = {
.frac_rate_policy = 1,
};
static const struct dv_info dv_dummy;
static int log_level;
struct vout_device_s hdmitx_vdev = {
.dv_info = &hdmitx_device.rxcap.dv_info,
.fresh_tx_hdr_pkt = hdmitx_set_drm_pkt,
@@ -157,6 +164,7 @@ static inline void hdmitx_notify_hpd(int hpd)
static void hdmitx_early_suspend(struct early_suspend *h)
{
struct hdmitx_dev *phdmi = (struct hdmitx_dev *)h->param;
struct hdmitx_dev *hdev = phdmi;
phdmi->ready = 0;
phdmi->hpd_lock = 1;
@@ -170,6 +178,12 @@ static void hdmitx_early_suspend(struct early_suspend *h)
phdmi->output_blank_flag = 0;
phdmi->hwop.cntlddc(phdmi, DDC_HDCP_MUX_INIT, 1);
phdmi->hwop.cntlddc(phdmi, DDC_HDCP_OP, HDCP14_OFF);
hdmitx_set_vsif_pkt(0, 0, NULL, true);
hdmitx_set_hdr10plus_pkt(0, NULL);
clear_rx_vinfo(hdev);
hdmitx_edid_clear(hdev);
hdmitx_edid_ram_buffer_clear(hdev);
edidinfo_detach_to_vinfo(hdev);
extcon_set_state_sync(hdmitx_extcon_power, EXTCON_DISP_HDMI, 0);
phdmi->hwop.cntlconfig(&hdmitx_device, CONF_CLR_AVI_PACKET, 0);
phdmi->hwop.cntlconfig(&hdmitx_device, CONF_CLR_VSDB_PACKET, 0);
@@ -425,6 +439,7 @@ static void hdrinfo_to_vinfo(struct vinfo_s *info, struct hdmitx_dev *hdev)
| (hdev->rxcap.hdr_sup_eotf_hdr << 1)
| (hdev->rxcap.hdr_sup_eotf_smpte_st_2084 << 2)
| (hdev->rxcap.hdr_sup_eotf_hlg << 3);
memcpy(info->hdr_info.rawdata, hdev->rxcap.hdr_rawdata, 7);
/*dynamic hdr*/
for (i = 0; i < 4; i++) {
if (hdev->rxcap.hdr_dynamic_info[i].type == 0) {
@@ -466,6 +481,38 @@ static void rxlatency_to_vinfo(struct vinfo_s *info, struct rx_cap *rx)
info->rx_latency.i_aLatency = rx->i_aLatency;
}
static void edidinfo_attach_to_vinfo(struct hdmitx_dev *hdev)
{
struct vinfo_s *info = NULL;
/* get current vinfo */
info = hdmitx_get_current_vinfo();
if ((info == NULL) || (info->name == NULL))
return;
if ((strncmp(info->name, "480cvbs", 7) == 0) ||
(strncmp(info->name, "576cvbs", 7) == 0) ||
(strncmp(info->name, "null", 4) == 0))
return;
hdrinfo_to_vinfo(info, hdev);
rxlatency_to_vinfo(info, &hdev->rxcap);
hdmitx_vdev.dv_info = &hdmitx_device.rxcap.dv_info;
}
static void edidinfo_detach_to_vinfo(struct hdmitx_dev *hdev)
{
struct vinfo_s *info = NULL;
/* get current vinfo */
info = hdmitx_get_current_vinfo();
if ((info == NULL) || (info->name == NULL))
return;
edidinfo_attach_to_vinfo(hdev);
hdmitx_vdev.dv_info = &dv_dummy;
}
static int set_disp_mode_auto(void)
{
int ret = -1;
@@ -492,13 +539,6 @@ static int set_disp_mode_auto(void)
/*update hdmi checksum to vout*/
memcpy(info->hdmichecksum, hdev->rxcap.chksum, 10);
if (!((strncmp(info->name, "480cvbs", 7) == 0) ||
(strncmp(info->name, "576cvbs", 7) == 0) ||
(strncmp(info->name, "null", 4) == 0))) {
hdrinfo_to_vinfo(info, hdev);
rxlatency_to_vinfo(info, &hdev->rxcap);
}
hdmi_physcial_size_update(hdev);
/* If info->name equals to cvbs, then set mode to I mode to hdmi
@@ -595,6 +635,8 @@ static int set_disp_mode_auto(void)
hdev->cur_VIC = vic;
hdev->output_blank_flag = 1;
hdev->ready = 1;
edidinfo_attach_to_vinfo(hdev);
return 1;
}
@@ -631,6 +673,7 @@ static int set_disp_mode_auto(void)
}
hdev->output_blank_flag = 1;
hdev->ready = 1;
edidinfo_attach_to_vinfo(hdev);
return ret;
}
@@ -1308,6 +1351,12 @@ static void hdr_work_func(struct work_struct *work)
}
}
#define hdmi_debug() \
do { \
if (log_level == 0xff) \
pr_info("%s[%d]\n", __func__, __LINE__); \
} while (0)
#define GET_LOW8BIT(a) ((a) & 0xff)
#define GET_HIGH8BIT(a) (((a) >> 8) & 0xff)
static void hdmitx_set_drm_pkt(struct master_display_info_s *data)
@@ -1316,6 +1365,7 @@ static void hdmitx_set_drm_pkt(struct master_display_info_s *data)
unsigned char DRM_HB[3] = {0x87, 0x1, 26};
static unsigned char DRM_DB[26] = {0x0};
hdmi_debug();
if (hdr_status_pos == 4) {
/* zero hdr10+ VSIF being sent - disable it */
pr_info("hdmitx_set_drm_pkt: disable hdr10+ zero vsif\n");
@@ -1521,6 +1571,7 @@ static void hdmitx_set_vsif_pkt(enum eotf_type type,
static enum eotf_type ltype = EOTF_T_NULL;
static uint8_t ltmode = -1;
hdmi_debug();
if ((hdev->ready == 0) || (hdev->rxcap.dv_info.ieeeoui
!= DV_IEEE_OUI)) {
ltype = EOTF_T_NULL;
@@ -1742,6 +1793,7 @@ static void hdmitx_set_hdr10plus_pkt(unsigned int flag,
unsigned char VEN_HB[3] = {0x81, 0x01, 0x1b};
unsigned char VEN_DB[27] = {0x00};
hdmi_debug();
if (flag == HDR10_PLUS_ZERO_VSIF) {
/* needed during hdr10+ to sdr transition */
pr_info("hdmitx_set_hdr10plus_pkt: zero vsif\n");
@@ -1827,6 +1879,7 @@ static void hdmitx_set_emp_pkt(unsigned char *data, unsigned int type,
unsigned int Data_Set_Tag = 0;
unsigned int Data_Set_Lemgth = 0;
hdmi_debug();
if (hdmitx_device.chip_type < MESON_CPU_ID_G12A) {
pr_info("this chip doesn't support emp function\n");
return;
@@ -4337,6 +4390,7 @@ static void hdmitx_hpd_plugout_handler(struct work_struct *work)
hdmitx_edid_clear(hdev);
hdmi_physcial_size_update(hdev);
hdmitx_edid_ram_buffer_clear(hdev);
edidinfo_detach_to_vinfo(hdev);
hdev->hpd_state = 0;
hdmitx_notify_hpd(hdev->hpd_state);
extcon_set_state_sync(hdmitx_extcon_hdmi, EXTCON_DISP_HDMI, 0);
@@ -5111,7 +5165,7 @@ static int amhdmitx_probe(struct platform_device *pdev)
hdmitx_device.task = kthread_run(hdmi_task_handle,
&hdmitx_device, "kthread_hdmi");
edidinfo_attach_to_vinfo(&hdmitx_device);
pr_info(SYS "amhdmitx_probe end\n");
return r;
@@ -5409,3 +5463,6 @@ static int __init hdmitx_boot_hdr_priority(char *str)
__setup("hdr_priority=", hdmitx_boot_hdr_priority);
MODULE_PARM_DESC(log_level, "\n log_level\n");
module_param(log_level, int, 0644);