video: tegra: dc: sysfs for HDMI AVI content type
Ahung Cheng [Tue, 14 Jun 2016 04:43:47 +0000 (12:43 +0800)]
Updated avi infoframe would be picked up by HW for next frame.

Sysfs node:
/sys/devices/platform/host1x/tegradc.1/hdmi_config/it_content_type
Value:
        0x0 = HDMI_AVI_IT_CONTENT_GRAPHICS,
        0x1 = HDMI_AVI_IT_CONTENT_PHOTO,
        0x2 = HDMI_AVI_IT_CONTENT_CINEMA,
        0x3 = HDMI_AVI_IT_CONTENT_GAME,
        0x4 = HDMI_AVI_IT_CONTENT_NONE, (Default)

bug 1772096

Change-Id: I9c9f79dcf0b6a9ff192ad0d457c55f38e21c2cfd
Signed-off-by: Ahung Cheng <ahcheng@nvidia.com>
Reviewed-on: http://git-master/r/1164025
(cherry picked from commit 708f5ad20644a2946f3e936e8c267333294d6408)
Signed-off-by: Ahung Cheng <ahcheng@nvidia.com>
Reviewed-on: http://git-master/r/1170952
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Animesh Kishore <ankishore@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Bibek Basu <bbasu@nvidia.com>

arch/arm/mach-tegra/include/mach/dc.h
drivers/video/tegra/dc/dc_sysfs.c
drivers/video/tegra/dc/hdmi2.0.c
drivers/video/tegra/dc/hdmi2.0.h

index 27bf001..1087953 100644 (file)
@@ -1185,6 +1185,8 @@ struct tegra_hdmi_out {
        int n_tmds_config;
        bool hdmi2fpd_bridge_enable;
        struct spd_infoframe *spd_infoframe;
+       void (*set_avi_infoframe)(struct tegra_dc *dc);
+       u8 it_content_type;
 };
 
 enum {
index 6cf5640..97f8181 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * drivers/video/tegra/dc/dc_sysfs.c
  *
- * Copyright (c) 2011-2015, NVIDIA CORPORATION, All rights reserved.
+ * Copyright (c) 2011-2016, NVIDIA CORPORATION, All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -704,6 +704,46 @@ static ssize_t dump_config_show(struct device *device,
 
 static DEVICE_ATTR(dump_config, S_IRUGO, dump_config_show, NULL);
 
+static ssize_t it_content_type_show(struct device *device,
+       struct device_attribute *attr, char *buf)
+{
+       struct platform_device *ndev = to_platform_device(device);
+       struct tegra_dc *dc = platform_get_drvdata(ndev);
+       struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
+       ssize_t res = 0;
+
+       res = snprintf(buf, PAGE_SIZE,
+               "%d\n",
+               hdmi_out->it_content_type);
+
+       return res;
+}
+
+static ssize_t it_content_type_store(struct device *dev,
+       struct device_attribute *attr, const char *buf, size_t count)
+{
+       struct platform_device *ndev = to_platform_device(dev);
+       struct tegra_dc *dc = platform_get_drvdata(ndev);
+       unsigned long val = 0;
+       struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
+
+       if (kstrtoul(buf, 10, &val) < 0)
+               return -EINVAL;
+
+       if (val < 0 || val > 4)
+               return -EINVAL;
+
+       hdmi_out->it_content_type = val;
+
+       if (hdmi_out && hdmi_out->set_avi_infoframe)
+               hdmi_out->set_avi_infoframe(dc);
+
+       return count;
+}
+
+static DEVICE_ATTR(it_content_type, S_IRUGO|S_IWUSR, it_content_type_show,
+               it_content_type_store);
+
 static struct attribute *hdmi_config_attrs[] = {
        &dev_attr_pclk.attr,
        &dev_attr_pll0.attr,
@@ -712,6 +752,7 @@ static struct attribute *hdmi_config_attrs[] = {
        &dev_attr_drive_current.attr,
        &dev_attr_peak_current.attr,
        &dev_attr_dump_config.attr,
+       &dev_attr_it_content_type.attr,
        NULL
 };
 
index 17c5461..47c8205 100644 (file)
@@ -916,6 +916,9 @@ static int tegra_dc_hdmi_init(struct tegra_dc *dc)
        hdmi->mon_spec_valid = false;
        hdmi->eld_valid = false;
        hdmi->device_shutdown = false;
+       hdmi->pdata->set_avi_infoframe = tegra_hdmi_set_avi_infoframe;
+       hdmi->pdata->it_content_type = HDMI_AVI_IT_CONTENT_NONE;
+
        if (0) {
                /* TODO: seamless boot mode needs initialize the state */
        } else {
@@ -1326,6 +1329,23 @@ static u32 tegra_hdmi_get_ycc_quant(struct tegra_hdmi *hdmi)
                return HDMI_AVI_YCC_QUANT_NONE;
 }
 
+static bool tegra_hdmi_get_it_content(struct tegra_hdmi *hdmi)
+{
+       int it_content = hdmi->pdata->it_content_type &
+               HDMI_AVI_IT_CONTENT_NONE;
+
+       if (it_content)
+               return false;
+       else
+               return true;
+}
+
+static int tegra_hdmi_get_it_content_type(struct tegra_hdmi *hdmi)
+{
+       int it_content_type = hdmi->pdata->it_content_type & 0x3;
+       return it_content_type;
+}
+
 static void tegra_hdmi_avi_infoframe_update(struct tegra_hdmi *hdmi)
 {
        struct hdmi_avi_infoframe *avi = &hdmi->avi;
@@ -1349,13 +1369,13 @@ static void tegra_hdmi_avi_infoframe_update(struct tegra_hdmi *hdmi)
        avi->scaling = HDMI_AVI_SCALING_UNKNOWN;
        avi->rgb_quant = tegra_hdmi_get_rgb_quant(hdmi);
        avi->ext_colorimetry = tegra_hdmi_get_ex_colorimetry(hdmi);
-       avi->it_content = HDMI_AVI_IT_CONTENT_FALSE;
+       avi->it_content = tegra_hdmi_get_it_content(hdmi);
 
        /* set correct vic if video format is cea defined else set 0 */
        avi->video_format = tegra_hdmi_find_cea_vic(hdmi);
 
        avi->pix_rep = HDMI_AVI_NO_PIX_REPEAT;
-       avi->it_content_type = HDMI_AVI_IT_CONTENT_NONE;
+       avi->it_content_type = tegra_hdmi_get_it_content_type(hdmi);
        avi->ycc_quant = tegra_hdmi_get_ycc_quant(hdmi);
 
        avi->top_bar_end_line_low_byte = 0;
@@ -1402,6 +1422,12 @@ static void tegra_hdmi_avi_infoframe(struct tegra_hdmi *hdmi)
                NV_SOR_HDMI_AVI_INFOFRAME_CTRL_CHECKSUM_ENABLE);
 }
 
+void tegra_hdmi_set_avi_infoframe(struct tegra_dc *dc)
+{
+       struct tegra_hdmi *hdmi = tegra_dc_get_outdata(dc);
+       tegra_hdmi_avi_infoframe(hdmi);
+}
+
 static int tegra_hdmi_get_extended_vic(const struct tegra_dc_mode *mode)
 {
        struct fb_videomode m;
index cfc01cd..2a60c23 100644 (file)
@@ -144,11 +144,11 @@ enum {
 };
 
 enum {
-       HDMI_AVI_IT_CONTENT_NONE = 0x0,
        HDMI_AVI_IT_CONTENT_GRAPHICS = 0x0,
        HDMI_AVI_IT_CONTENT_PHOTO = 0x1,
        HDMI_AVI_IT_CONTENT_CINEMA = 0x2,
        HDMI_AVI_IT_CONTENT_GAME = 0x3,
+       HDMI_AVI_IT_CONTENT_NONE = 0x4,
 };
 
 enum {
@@ -482,5 +482,6 @@ void tegra_hdmi_infoframe_pkt_write(struct tegra_hdmi *hdmi,
                                                u32 reg_payload_len,
                                                bool sw_checksum);
 u32 tegra_hdmi_get_cea_modedb_size(struct tegra_hdmi *hdmi);
+void tegra_hdmi_set_avi_infoframe(struct tegra_dc *dc);
 
 #endif