hdmitx: fix valid_mode effects color attribute [1/1]
authorZongdong Jiao <zongdong.jiao@amlogic.com>
Wed, 12 Jun 2019 12:19:45 +0000 (20:19 +0800)
committerNick Xie <nick@khadas.com>
Mon, 5 Aug 2019 07:17:58 +0000 (15:17 +0800)
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 <zongdong.jiao@amlogic.com>
drivers/amlogic/media/vout/hdmitx/hdmi_common/hdmi_parameters.c
drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c
include/linux/amlogic/media/vout/hdmi_tx/hdmi_common.h

index ad39b0e..30305da 100644 (file)
@@ -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;
index 2583426..fdac98c 100644 (file)
@@ -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;
 }
 
index 0e72fdf..e640616 100644 (file)
@@ -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);