From c4b298e0ec2635916be7e1f1622b72e619e403f9 Mon Sep 17 00:00:00 2001 From: Zongdong Jiao Date: Wed, 12 Jun 2019 20:19:45 +0800 Subject: [PATCH] hdmitx: fix valid_mode effects color attribute [1/1] PD#OTT-4372 Problem: Need add a extra hdmi_format_para for valid_mode Solution: Add a extra hdmi_format_para for valid_mode Also, fix cedst_en assginment and wrong aud ACR/N parameters when kernel bootup, need to get current vinfo then set right ARC/N. Verify: G12/U212 Change-Id: Ib59986d7436a578daeb7055aa41a379e9381a99b Signed-off-by: Zongdong Jiao --- .../vout/hdmitx/hdmi_common/hdmi_parameters.c | 65 ++++++++++++++++++++++ .../media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c | 17 +++++- .../linux/amlogic/media/vout/hdmi_tx/hdmi_common.h | 1 + 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_common/hdmi_parameters.c b/drivers/amlogic/media/vout/hdmitx/hdmi_common/hdmi_parameters.c index ad39b0e..30305da 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_common/hdmi_parameters.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_common/hdmi_parameters.c @@ -2853,6 +2853,71 @@ struct hdmi_format_para *hdmi_get_fmt_name(char const *name, char const *attr) return para; } +static struct hdmi_format_para tst_para; +static inline void copy_para(struct hdmi_format_para *des, + struct hdmi_format_para *src) +{ + if (!des || !src) + return; + memcpy(des, src, sizeof(struct hdmi_format_para)); +} + +struct hdmi_format_para *hdmi_tst_fmt_name(char const *name, char const *attr) +{ + int i; + char *lname; + enum hdmi_vic vic = HDMI_Unknown; + + copy_para(&tst_para, &fmt_para_non_hdmi_fmt); + if (!name) + return &tst_para; + + for (i = 0; all_fmt_paras[i]; i++) { + lname = all_fmt_paras[i]->name; + if (lname && (strncmp(name, lname, strlen(lname)) == 0)) { + vic = all_fmt_paras[i]->vic; + break; + } + lname = all_fmt_paras[i]->sname; + if (lname && (strncmp(name, lname, strlen(lname)) == 0)) { + vic = all_fmt_paras[i]->vic; + break; + } + } + if ((vic != HDMI_Unknown) && (i != sizeof(all_fmt_paras) / + sizeof(struct hdmi_format_para *))) { + copy_para(&tst_para, all_fmt_paras[i]); + memset(&tst_para.ext_name[0], 0, sizeof(tst_para.ext_name)); + memcpy(&tst_para.ext_name[0], name, sizeof(tst_para.ext_name)); + hdmi_parse_attr(&tst_para, name); + hdmi_parse_attr(&tst_para, attr); + } else { + copy_para(&tst_para, &fmt_para_non_hdmi_fmt); + hdmi_parse_attr(&tst_para, name); + hdmi_parse_attr(&tst_para, attr); + } + if (strstr(name, "420")) + tst_para.cs = COLORSPACE_YUV420; + + /* only 2160p60/50hz smpte60/50hz have Y420 mode */ + if (tst_para.cs == COLORSPACE_YUV420) { + switch ((tst_para.vic) & 0xff) { + case HDMI_3840x2160p50_16x9: + case HDMI_3840x2160p60_16x9: + case HDMI_4096x2160p50_256x135: + case HDMI_4096x2160p60_256x135: + case HDMI_3840x2160p50_64x27: + case HDMI_3840x2160p60_64x27: + break; + default: + copy_para(&tst_para, &fmt_para_non_hdmi_fmt); + break; + } + } + + return &tst_para; +} + struct vinfo_s *hdmi_get_valid_vinfo(char *mode) { int i; diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c index 2583426..fdac98c 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c @@ -2607,7 +2607,7 @@ static ssize_t show_valid_mode(struct device *dev, valid_mode); return pos; } - para = hdmi_get_fmt_name(cvalid_mode, cvalid_mode); + para = hdmi_tst_fmt_name(cvalid_mode, cvalid_mode); } if (para) { pr_info(SYS "sname = %s\n", para->sname); @@ -3062,6 +3062,8 @@ static ssize_t store_cedst_policy(struct device *dev, } if (val == 2) /* Force mode */ hdev->cedst_policy = 1; + /* assgin cedst_en from dts or here */ + hdev->cedst_en = hdev->cedst_policy; } else pr_info("only accept as 0, 1(auto), or 2(force)\n"); } @@ -4034,6 +4036,7 @@ static void hdmitx_cedst_process(struct work_struct *work) static void hdmitx_hpd_plugin_handler(struct work_struct *work) { char bksv_buf[5]; + struct vinfo_s *info = NULL; struct hdmitx_dev *hdev = container_of((struct delayed_work *)work, struct hdmitx_dev, work_hpd_plugin); @@ -4078,7 +4081,9 @@ static void hdmitx_hpd_plugin_handler(struct work_struct *work) } set_disp_mode_auto(); - hdmitx_set_audio(hdev, &(hdev->cur_audio_param)); + info = hdmitx_get_current_vinfo(); + if (info && (info->mode == VMODE_HDMI)) + hdmitx_set_audio(hdev, &(hdev->cur_audio_param)); hdev->hpd_state = 1; hdmitx_notify_hpd(hdev->hpd_state); @@ -4183,6 +4188,7 @@ int tv_audio_support(int type, struct rx_cap *pRXCap) static int hdmi_task_handle(void *data) { + struct vinfo_s *info = NULL; struct hdmitx_dev *hdmitx_device = (struct hdmitx_dev *)data; hdmitx_extcon_hdmi->state = !!(hdmitx_device->HWOp.CntlMisc( @@ -4226,6 +4232,13 @@ static int hdmi_task_handle(void *data) MISC_TRIGGER_HPD, 0); hdmitx_device->hdmi_init = 1; + info = hdmitx_get_current_vinfo(); + if (!info || !info->name) + return 0; + if (info->mode == VMODE_HDMI) + hdmitx_device->para = hdmi_get_fmt_name(info->name, + hdmitx_device->fmt_attr); + return 0; } diff --git a/include/linux/amlogic/media/vout/hdmi_tx/hdmi_common.h b/include/linux/amlogic/media/vout/hdmi_tx/hdmi_common.h index 0e72fdf..e640616 100644 --- a/include/linux/amlogic/media/vout/hdmi_tx/hdmi_common.h +++ b/include/linux/amlogic/media/vout/hdmi_tx/hdmi_common.h @@ -395,6 +395,7 @@ unsigned int hdmi_get_csc_coef( unsigned int color_depth, unsigned int color_format, unsigned char **coef_array, unsigned int *coef_length); struct hdmi_format_para *hdmi_get_fmt_name(char const *name, char const *attr); +struct hdmi_format_para *hdmi_tst_fmt_name(char const *name, char const *attr); struct vinfo_s *hdmi_get_valid_vinfo(char *mode); const char *hdmi_get_str_cd(struct hdmi_format_para *para); const char *hdmi_get_str_cs(struct hdmi_format_para *para); -- 2.7.4