]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
tegra: dc: Add hdr support
authorArun Swain <arswain@nvidia.com>
Wed, 23 Sep 2015 21:34:18 +0000 (14:34 -0700)
committermobile promotions <svcmobile_promotions@nvidia.com>
Fri, 23 Oct 2015 01:51:10 +0000 (18:51 -0700)
Added HDR support in kernel using the new FLIP4.

1. Added support for new HDR infoframe defined
in CEA 861.3.
2. This new infoframe data is associated with each
flip and passed onto kernel from userspace. The
user space uses tegra_dc_ext_hdr struct and the
appropriate tag info in the new FLIP4 ioctl to
pass the info to kernel.
3. The new infoframe data in the ioctl is parsed
and stored in existing tegra_dc_ext_flip_data
struct in the flip ioctl. This info is passed to
dc in flip_worker.
4. Currently the design is to set the eotf as 0
(SDR) and 2(SMPTE 2084) with the required payload
for non-HDR and HDR frames respectively.

Bug 200122117

Change-Id: Ic66fa88db50177ccd0349bbf7a6ff9f33c4eb764
Reviewed-on: http://git-master/r/803998
(cherry picked from commit 3f6e9e9531360eedba5ce43c5d129f34b6d7f68b)
Signed-off-by: Arun Swain <arswain@nvidia.com>
Reviewed-on: http://git-master/r/821201
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Mitch Luban <mluban@nvidia.com>
GVS: Gerrit_Virtual_Submit

arch/arm/mach-tegra/include/mach/dc.h
drivers/video/tegra/dc/dc.c
drivers/video/tegra/dc/dc_priv.h
drivers/video/tegra/dc/dc_priv_defs.h
drivers/video/tegra/dc/ext/dev.c
drivers/video/tegra/dc/hda_dc.c
drivers/video/tegra/dc/hdmi2.0.c
drivers/video/tegra/dc/hdmi2.0.h
drivers/video/tegra/dc/sor_regs.h
include/video/tegra_dc_ext.h

index 04d0cd954a89654621d50bca4d40d5288ebb16db..c0ef09b1875bfbbdafb3d869e8e9ff501ccd8f35 100644 (file)
@@ -829,6 +829,13 @@ struct tegra_dc_cmu {
 };
 #endif
 
+struct tegra_dc_hdr {
+       bool            enabled;
+       u32             eotf;
+       u32             static_metadata_id;
+       u8              static_metadata[24];
+};
+
 struct tegra_dc_win {
        u8                      idx;
        u8                      ppflags; /* see TEGRA_WIN_PPFLAG* */
index 49dff178c962eac2799cbb2c388a179dcbfce2bf..887a5a3fcb541eaf336c2b24701974f1d84ab2c9 100644 (file)
@@ -2203,6 +2203,38 @@ int tegra_dc_update_cmu(struct tegra_dc *dc, struct tegra_dc_cmu *cmu)
 }
 EXPORT_SYMBOL(tegra_dc_update_cmu);
 
+int tegra_dc_set_hdr(struct tegra_dc *dc, struct tegra_dc_hdr *hdr,
+                                               bool cache_dirty)
+{
+       int ret;
+
+       mutex_lock(&dc->lock);
+
+       if (!dc->enabled) {
+               mutex_unlock(&dc->lock);
+               return 0;
+       }
+       if (cache_dirty) {
+               dc->hdr.eotf = hdr->eotf;
+               dc->hdr.static_metadata_id = hdr->static_metadata_id;
+               memcpy(dc->hdr.static_metadata, hdr->static_metadata,
+                                       sizeof(dc->hdr.static_metadata));
+       } else if (dc->hdr.enabled == hdr->enabled) {
+               mutex_unlock(&dc->lock);
+               return 0;
+       }
+       dc->hdr.enabled = hdr->enabled;
+       dc->hdr_cache_dirty = true;
+       if (!dc->hdr.enabled)
+               memset(&dc->hdr, 0, sizeof(dc->hdr));
+       ret = _tegra_dc_config_frame_end_intr(dc, true);
+
+       mutex_unlock(&dc->lock);
+
+       return ret;
+}
+EXPORT_SYMBOL(tegra_dc_set_hdr);
+
 static int _tegra_dc_update_cmu_aligned(struct tegra_dc *dc,
                                struct tegra_dc_cmu *cmu,
                                bool force)
@@ -3048,11 +3080,30 @@ static void tegra_dc_vblank(struct work_struct *work)
                } \
        } while (0)
 
+static void _tegra_dc_handle_hdr(struct tegra_dc *dc)
+{
+       mutex_lock(&dc->lock);
+       if (!dc->enabled) {
+               mutex_unlock(&dc->lock);
+               return;
+       }
+
+       tegra_dc_get(dc);
+
+       if (dc->out_ops->set_hdr)
+               dc->out_ops->set_hdr(dc);
+
+       tegra_dc_put(dc);
+       mutex_unlock(&dc->lock);
+
+       return;
+}
+
 static void tegra_dc_frame_end(struct work_struct *work)
 {
-#ifdef CONFIG_TEGRA_DC_CMU
        struct tegra_dc *dc = container_of(work,
                struct tegra_dc, frame_end_work);
+#ifdef CONFIG_TEGRA_DC_CMU
        u32 val;
        u32 i;
 
@@ -3106,6 +3157,12 @@ static void tegra_dc_frame_end(struct work_struct *work)
        tegra_dc_put(dc);
        mutex_unlock(&dc->lock);
 #endif
+       if (dc->hdr_cache_dirty) {
+               _tegra_dc_handle_hdr(dc);
+               _tegra_dc_config_frame_end_intr(dc, false);
+               dc->hdr_cache_dirty = false;
+       }
+       return;
 }
 
 static void tegra_dc_one_shot_worker(struct work_struct *work)
index 279e29f8eac54e80d5aaa1b1d49f8fc51c5a039e..712759ffb33e28a1f1c6646fc0d1fc7b6b98a330 100644 (file)
@@ -574,6 +574,9 @@ int tegra_dc_update_cmu(struct tegra_dc *dc, struct tegra_dc_cmu *cmu);
 int tegra_dc_update_cmu_aligned(struct tegra_dc *dc, struct tegra_dc_cmu *cmu);
 #endif
 
+int tegra_dc_set_hdr(struct tegra_dc *dc, struct tegra_dc_hdr *hdr,
+                                       bool cache_dirty);
+
 struct device_node *tegra_get_panel_node_out_type_check
        (struct tegra_dc *dc, u32 out_type);
 
index 1f68d728c9148f6555235747e82da1f9ab697f27..a362bfc86b442b1e064fae539d376fb051e7b299 100644 (file)
@@ -134,6 +134,7 @@ struct tegra_dc_out_ops {
        /* Set up VRR mode */
        void (*vrr_mode)(const struct tegra_dc *dc,
                        struct fb_videomode *mode);
+       int (*set_hdr)(struct tegra_dc *dc);
 };
 
 struct tegra_dc_shift_clk_div {
@@ -204,6 +205,7 @@ struct tegra_dc {
 
        struct tegra_dc_blend           blend;
        int                             n_windows;
+       struct tegra_dc_hdr             hdr;
 
 #if defined(CONFIG_TEGRA_DC_CMU)
        struct tegra_dc_cmu             cmu;
@@ -315,5 +317,6 @@ struct tegra_dc {
        struct notifier_block slgc_notifier;
        bool    vedid;
        u8      *vedid_data;
+       bool    hdr_cache_dirty;
 };
 #endif
index fdf25cb01e7880a5685d7a2d1d3557a5a249d4fe..eb7f280569c61aad225273433fa75de1b73968b1 100644 (file)
@@ -125,6 +125,8 @@ struct tegra_dc_ext_flip_data {
        u16 dirty_rect[4];
        bool dirty_rect_valid;
        u8 flags;
+       struct tegra_dc_hdr hdr_data;
+       bool hdr_cache_dirty;
 };
 
 static int tegra_dc_ext_set_vblank(struct tegra_dc_ext *ext, bool enable);
@@ -814,6 +816,9 @@ static void tegra_dc_ext_flip_worker(struct kthread_work *work)
 
        trace_sync_wt_ovr_syncpt_upd((data->win[win_num-1]).syncpt_max);
 
+       if (dc->enabled && !skip_flip)
+               tegra_dc_set_hdr(dc, &data->hdr_data, data->hdr_cache_dirty);
+
        if (dc->enabled && !skip_flip) {
                dc->blanked = false;
                if (dc->out_ops && dc->out_ops->vrr_enable)
@@ -1108,10 +1113,37 @@ static void tegra_dc_ext_read_user_data(struct tegra_dc_ext_flip_data *data,
                        struct tegra_dc_ext_flip_user_data *flip_user_data,
                        int nr_user_data)
 {
-       /*Add support for reading user data (HDR data for intance) here*/
+       int i = 0;
+
+       for (i = 0; i < nr_user_data; i++) {
+               struct tegra_dc_hdr *hdr;
+               struct tegra_dc_ext_hdr *info;
+               switch (flip_user_data[0].data_type) {
+               case TEGRA_DC_EXT_FLIP_USER_DATA_HDR_DATA:
+                       hdr = &data->hdr_data;
+                       info = &flip_user_data[i].hdr_info;
+                       if (flip_user_data[i].flags &
+                               TEGRA_DC_EXT_FLIP_FLAG_HDR_ENABLE)
+                               hdr->enabled = true;
+                       if (flip_user_data[i].flags &
+                               TEGRA_DC_EXT_FLIP_FLAG_HDR_DATA_UPDATED) {
+                               data->hdr_cache_dirty = true;
+                               hdr->eotf = info->eotf;
+                               hdr->static_metadata_id =
+                                               info->static_metadata_id;
+                               memcpy(hdr->static_metadata,
+                                       info->static_metadata,
+                                       sizeof(hdr->static_metadata));
+                       }
+                       break;
+               default:
+                       dev_err(&data->ext->dc->ndev->dev,
+                               "Invalid FLIP_USER_DATA_TYPE\n");
+               }
+       }
+       return;
 }
 
-
 static int tegra_dc_ext_flip(struct tegra_dc_ext_user *user,
                             struct tegra_dc_ext_flip_windowattr *win,
                             int win_num,
index d87c7b19e9614a85f999f9c39e303ca5283fe252..6b5b1566337b30d88e1154a7ef1078234f71b9fe 100644 (file)
@@ -169,7 +169,8 @@ static void tegra_hdmi_audio_infoframe(void)
                                HDMI_INFOFRAME_VS_AUDIO,
                                HDMI_INFOFRAME_LEN_AUDIO,
                                &to_hdmi(hda->client_data)->audio,
-                               sizeof(to_hdmi(hda->client_data)->audio));
+                               sizeof(to_hdmi(hda->client_data)->audio),
+                               false);
        }
 
        /* Send infoframe every frame, checksum hw generated */
index 2430d33b35c7eeb068b0437d4b1e99a78b3f81f1..b0cd269cc58779c986f2df997ee69d17bbb9ba5c 100644 (file)
@@ -1106,7 +1106,8 @@ void tegra_hdmi_infoframe_pkt_write(struct tegra_hdmi *hdmi,
                                                u32 header_reg, u8 pkt_type,
                                                u8 pkt_vs, u8 pkt_len,
                                                void *reg_payload,
-                                               u32 reg_payload_len)
+                                               u32 reg_payload_len,
+                                               bool sw_checksum)
 {
        struct tegra_dc_sor_data *sor = hdmi->sor;
        u32 val;
@@ -1118,6 +1119,17 @@ void tegra_hdmi_infoframe_pkt_write(struct tegra_hdmi *hdmi,
                NV_SOR_HDMI_INFOFRAME_HEADER_LEN(pkt_len);
        tegra_sor_writel(sor, header_reg, val);
 
+       if (sw_checksum) {
+               u8 checksum = pkt_type + pkt_vs + pkt_len;
+
+               for (val = 1; val <= pkt_len; val++)
+                       checksum += ((u8 *)reg_payload)[val];
+
+               /* The first byte of the payload must always be the checksum
+                * that we are going to calculate in SW */
+               ((u8 *)reg_payload)[0] = (256 - checksum);
+       }
+
        for (val = 0; val < reg_payload_len; val += 4, data_reg++, data++)
                tegra_sor_writel(sor, data_reg, *data);
 }
@@ -1367,7 +1379,8 @@ static void tegra_hdmi_avi_infoframe(struct tegra_hdmi *hdmi)
                                        HDMI_INFOFRAME_TYPE_AVI,
                                        HDMI_INFOFRAME_VS_AVI,
                                        HDMI_INFOFRAME_LEN_AVI,
-                                       &hdmi->avi, sizeof(hdmi->avi));
+                                       &hdmi->avi, sizeof(hdmi->avi),
+                                       false);
 
        /* Send infoframe every frame, checksum hw generated */
        tegra_sor_writel(sor, NV_SOR_HDMI_AVI_INFOFRAME_CTRL,
@@ -1458,7 +1471,8 @@ static void tegra_hdmi_vendor_infoframe(struct tegra_hdmi *hdmi)
                                        HDMI_INFOFRAME_TYPE_VENDOR,
                                        HDMI_INFOFRAME_VS_VENDOR,
                                        HDMI_INFOFRAME_LEN_VENDOR_LLC,
-                                       &hdmi->vsi, sizeof(hdmi->vsi));
+                                       &hdmi->vsi, sizeof(hdmi->vsi),
+                                       false);
 
        /* Send infoframe every frame, checksum hw generated */
        tegra_sor_writel(sor, NV_SOR_HDMI_VSI_INFOFRAME_CTRL,
@@ -1470,6 +1484,85 @@ static void tegra_hdmi_vendor_infoframe(struct tegra_hdmi *hdmi)
 #undef HDMI_INFOFRAME_LEN_VENDOR_LLC
 }
 
+static void tegra_hdmi_hdr_infoframe_update(struct tegra_hdmi *hdmi)
+{
+       struct hdmi_hdr_infoframe *hdr = &hdmi->hdr;
+
+       memset(&hdmi->hdr, 0, sizeof(hdmi->hdr));
+
+       if (tegra_platform_is_linsim())
+               return;
+
+       hdr->eotf = hdmi->dc->hdr.eotf;
+       hdr->static_metadata_id = hdmi->dc->hdr.static_metadata_id;
+
+       /* PB3-14 : Group 1 : Static Metadata*/
+       hdr->display_primaries_x_0_lsb = hdmi->dc->hdr.static_metadata[0];
+       hdr->display_primaries_x_0_msb = hdmi->dc->hdr.static_metadata[1];
+       hdr->display_primaries_y_0_lsb = hdmi->dc->hdr.static_metadata[2];
+       hdr->display_primaries_y_0_msb = hdmi->dc->hdr.static_metadata[3];
+       hdr->display_primaries_x_1_lsb = hdmi->dc->hdr.static_metadata[4];
+       hdr->display_primaries_x_1_msb = hdmi->dc->hdr.static_metadata[5];
+       hdr->display_primaries_y_1_lsb = hdmi->dc->hdr.static_metadata[6];
+       hdr->display_primaries_y_1_msb = hdmi->dc->hdr.static_metadata[7];
+       hdr->display_primaries_x_2_lsb = hdmi->dc->hdr.static_metadata[8];
+       hdr->display_primaries_x_2_msb = hdmi->dc->hdr.static_metadata[9];
+       hdr->display_primaries_y_2_lsb = hdmi->dc->hdr.static_metadata[10];
+       hdr->display_primaries_y_2_msb = hdmi->dc->hdr.static_metadata[11];
+
+       /* PB15-18 : Group 2 : Static Metadata*/
+       hdr->white_point_x_lsb = hdmi->dc->hdr.static_metadata[12];
+       hdr->white_point_x_msb = hdmi->dc->hdr.static_metadata[13];
+       hdr->white_point_y_lsb = hdmi->dc->hdr.static_metadata[14];
+       hdr->white_point_y_msb = hdmi->dc->hdr.static_metadata[15];
+
+       /* PB19-20 : Group 3 : Static Metadata*/
+       hdr->max_display_mastering_luminance_lsb =
+                                       hdmi->dc->hdr.static_metadata[16];
+       hdr->max_display_mastering_luminance_msb =
+                                       hdmi->dc->hdr.static_metadata[17];
+
+       /* PB21-22 : Group 4 : Static Metadata*/
+       hdr->min_display_mastering_luminance_lsb =
+                                       hdmi->dc->hdr.static_metadata[18];
+       hdr->min_display_mastering_luminance_msb =
+                                       hdmi->dc->hdr.static_metadata[19];
+
+       /* PB23-24 : Group 5 : Static Metadata*/
+       hdr->max_content_light_level_lsb = hdmi->dc->hdr.static_metadata[20];
+       hdr->max_content_light_level_msb = hdmi->dc->hdr.static_metadata[21];
+
+       /* PB25-26 : Group 6 : Static Metadata*/
+       hdr->max_frame_avg_light_level_lsb = hdmi->dc->hdr.static_metadata[22];
+       hdr->min_frame_avg_light_level_msb = hdmi->dc->hdr.static_metadata[23];
+
+       return;
+}
+
+static void tegra_hdmi_hdr_infoframe(struct tegra_hdmi *hdmi)
+{
+       struct tegra_dc_sor_data *sor = hdmi->sor;
+
+       /* disable generic infoframe before configuring */
+       tegra_sor_writel(sor, NV_SOR_HDMI_GENERIC_CTRL, 0);
+
+       tegra_hdmi_hdr_infoframe_update(hdmi);
+
+       tegra_hdmi_infoframe_pkt_write(hdmi, NV_SOR_HDMI_GENERIC_HEADER,
+                                       HDMI_INFOFRAME_TYPE_HDR,
+                                       HDMI_INFOFRAME_VS_HDR,
+                                       HDMI_INFOFRAME_LEN_HDR,
+                                       &hdmi->hdr, sizeof(hdmi->hdr),
+                                       true);
+
+       /* Send infoframe every frame, checksum hw generated */
+       tegra_sor_writel(sor, NV_SOR_HDMI_GENERIC_CTRL,
+               NV_SOR_HDMI_GENERIC_CTRL_ENABLE_YES |
+               NV_SOR_HDMI_GENERIC_CTRL_OTHER_DISABLE |
+               NV_SOR_HDMI_GENERIC_CTRL_SINGLE_DISABLE);
+       return;
+}
+
 __maybe_unused
 static int tegra_hdmi_scdc_read(struct tegra_hdmi *hdmi,
                                        u8 offset_data[][2], u32 n_entries)
@@ -2060,6 +2153,16 @@ static void tegra_dc_hdmi_resume(struct tegra_dc *dc)
                                msecs_to_jiffies(HDMI_HPD_DEBOUNCE_DELAY_MS));
 }
 
+static int tegra_dc_hdmi_set_hdr(struct tegra_dc *dc)
+{
+       u16 ret = 0;
+       struct tegra_hdmi *hdmi = tegra_dc_get_outdata(dc);
+       ret = tegra_edid_get_ex_hdr_cap(hdmi->edid);
+       if (ret & FB_CAP_HDR)
+               tegra_hdmi_hdr_infoframe(hdmi);
+       return 0;
+}
+
 static int tegra_dc_hdmi_ddc_enable(struct tegra_dc *dc)
 {
        struct tegra_hdmi *hdmi = tegra_dc_get_outdata(dc);
@@ -2255,4 +2358,5 @@ struct tegra_dc_out_ops tegra_dc_hdmi2_0_ops = {
        .hpd_state = tegra_dc_hdmi_hpd_state,
        .vrr_enable = tegra_dc_hdmi_vrr_enable,
        .vrr_mode = tegra_hdmi_update_vrr_mode,
+       .set_hdr = tegra_dc_hdmi_set_hdr,
 };
index 546510d3cd5dbcffcdf3166e9b7c17cccd81fb1e..c1d598a86057f807e9d1d87c34b03e181e149b4c 100644 (file)
@@ -38,6 +38,7 @@ enum {
        HDMI_INFOFRAME_TYPE_SPD = 0x83,
        HDMI_INFOFRAME_TYPE_AUDIO = 0x84,
        HDMI_INFOFRAME_TYPE_MPEG_SRC = 0x85,
+       HDMI_INFOFRAME_TYPE_HDR = 0x87,
 };
 
 enum {
@@ -46,6 +47,7 @@ enum {
        HDMI_INFOFRAME_VS_SPD = 0x1,
        HDMI_INFOFRAME_VS_AUDIO = 0x1,
        HDMI_INFOFRAME_VS_MPEG_SRC = 0x1,
+       HDMI_INFOFRAME_VS_HDR = 0x1,
 };
 
 /* excluding checksum and header bytes */
@@ -55,6 +57,7 @@ enum {
        HDMI_INFOFRAME_LEN_SPD = 25,
        HDMI_INFOFRAME_LEN_AUDIO = 10,
        HDMI_INFOFRAME_LEN_MPEG_SRC = 10,
+       HDMI_INFOFRAME_LEN_HDR = 26,
 };
 
 enum {
@@ -201,6 +204,60 @@ struct hdmi_avi_infoframe {
        u32 reg_hole2:8;
 } __packed;
 
+struct hdmi_hdr_infoframe {
+       /* PB0 */
+       u32 csum:8;     /* checksum */
+
+       /* PB1 */
+       u32 eotf:3;     /* The EOTF requested by the source */
+       u32 res1:5;     /* reserved */
+
+       /* PB2 */
+       u32 static_metadata_id:3; /* The id of the following static metadata */
+       u32 res2:5;     /* reserved */
+
+       /* PB3-14 : Group 1 : Static Metadata*/
+       u32 display_primaries_x_0_lsb:8;
+       u32 display_primaries_x_0_msb:8;
+       u32 display_primaries_y_0_lsb:8;
+       u32 display_primaries_y_0_msb:8;
+       u32 reg_hole1:8;
+       u32 display_primaries_x_1_lsb:8;
+       u32 display_primaries_x_1_msb:8;
+       u32 display_primaries_y_1_lsb:8;
+       u32 display_primaries_y_1_msb:8;
+       u32 display_primaries_x_2_lsb:8;
+       u32 display_primaries_x_2_msb:8;
+       u32 display_primaries_y_2_lsb:8;
+       u32 reg_hole2:8;
+       u32 display_primaries_y_2_msb:8;
+
+       /* PB15-18 : Group 2 : Static Metadata*/
+       u32 white_point_x_lsb:8;
+       u32 white_point_x_msb:8;
+       u32 white_point_y_lsb:8;
+       u32 white_point_y_msb:8;
+
+       /* PB19-20 : Group 3 : Static Metadata*/
+       u32 max_display_mastering_luminance_lsb:8;
+       u32 max_display_mastering_luminance_msb:8;
+
+       u32 reg_hole3:8;
+
+       /* PB21-22 : Group 4 : Static Metadata*/
+       u32 min_display_mastering_luminance_lsb:8;
+       u32 min_display_mastering_luminance_msb:8;
+
+       /* PB23-24 : Group 5 : Static Metadata*/
+       u32 max_content_light_level_lsb:8;
+       u32 max_content_light_level_msb:8;
+
+       /* PB25-26 : Group 6 : Static Metadata*/
+       u32 max_frame_avg_light_level_lsb:8;
+       u32 min_frame_avg_light_level_msb:8;
+
+} __packed;
+
 enum {
        HDMI_AUDIO_CHANNEL_CNT_STREAM,  /* refer to audio stream header */
        HDMI_AUDIO_CHANNEL_CNT_2,
@@ -284,6 +341,7 @@ struct tegra_hdmi {
        struct tegra_hdmi_out *pdata;
        struct tegra_dc_sor_data *sor;
        struct hdmi_avi_infoframe avi;
+       struct hdmi_hdr_infoframe hdr;
        bool enabled;
        atomic_t clock_refcount;
 
@@ -358,6 +416,7 @@ void tegra_hdmi_infoframe_pkt_write(struct tegra_hdmi *hdmi,
                                                u32 header_reg, u8 pkt_type,
                                                u8 pkt_vs, u8 pkt_len,
                                                void *reg_payload,
-                                               u32 reg_payload_len);
+                                               u32 reg_payload_len,
+                                               bool sw_checksum);
 
 #endif
index a02920e5556f47663bd0ea9711569f1f493c5bab..78523c5fa7c5f9dadc5f2061cfcbdd7de99b9db1 100644 (file)
 #define NV_SOR_REFCLK_DIV_INT(x)               (((x) & 0xff) << 8)
 #define NV_SOR_REFCLK_DIV_FRAC(x)              (((x) & 0x3) << 6)
 #define NV_SOR_AUDIO_CTRL                      0xfc
+
+#define NV_SOR_HDMI_GENERIC_CTRL                       0xa6
+#define NV_SOR_HDMI_GENERIC_CTRL_AUDIO_ENABLE                  (1 << 16)
+#define NV_SOR_HDMI_GENERIC_CTRL_AUDIO_DISABLE                 (0 << 16)
+#define NV_SOR_HDMI_GENERIC_CTRL_HBLANK_ENABLE                 (1 << 12)
+#define NV_SOR_HDMI_GENERIC_CTRL_HBLANK_DISABLE                        (0 << 12)
+#define NV_SOR_HDMI_GENERIC_CTRL_SINGLE_ENABLE                 (1 << 8)
+#define NV_SOR_HDMI_GENERIC_CTRL_SINGLE_DISABLE                        (0 << 8)
+#define NV_SOR_HDMI_GENERIC_CTRL_OTHER_ENABLE                  (1 << 4)
+#define NV_SOR_HDMI_GENERIC_CTRL_OTHER_DISABLE                 (0 << 4)
+#define NV_SOR_HDMI_GENERIC_CTRL_ENABLE_YES                            (1 << 0)
+#define NV_SOR_HDMI_GENERIC_CTRL_ENABLE_NO                             (0 << 0)
+#define NV_SOR_HDMI_GENERIC_HEADER             0xa8
+#define NV_SOR_HDMI_GENERIC_SUBPACK0_LOW               0xa9
+#define NV_SOR_HDMI_GENERIC_SUBPACK0_HIGH              0xaa
+#define NV_SOR_HDMI_GENERIC_SUBPACK1_LOW               0xab
+#define NV_SOR_HDMI_GENERIC_SUBPACK1_HIGH              0xac
+#define NV_SOR_HDMI_GENERIC_SUBPACK2_LOW               0xad
+#define NV_SOR_HDMI_GENERIC_SUBPACK2_HIGH              0xae
+#define NV_SOR_HDMI_GENERIC_SUBPACK3_LOW               0xaf
+#define NV_SOR_HDMI_GENERIC_SUBPACK3_HIGH              0xb0
 #define NV_SOR_AUDIO_CTRL_AFIFO_FLUSH          (1 << 12)
 #define NV_SOR_AUDIO_CTRL_SRC_HDA              (0x2 << 20)
 #define NV_SOR_AUDIO_CTRL_NULL_SAMPLE_EN       (1 << 29)
index 2ed3f29dec04379c26af88ed417e8c072f78f39c..8d224771bd0e954ee3c5725e79a7cced99efaf45 100644 (file)
 #define TEGRA_DC_EXT_FLIP_HEAD_FLAG_VRR_MODE   (1 << 1)
 /* Flag to notify attr v2 struct is being used */
 #define TEGRA_DC_EXT_FLIP_HEAD_FLAG_V2_ATTR    (1 << 2)
-
+/* Flag for HDR_DATA handling */
+#define TEGRA_DC_EXT_FLIP_FLAG_HDR_ENABLE      (1 << 0)
+#define TEGRA_DC_EXT_FLIP_FLAG_HDR_DATA_UPDATED (1 << 1)
 
 struct tegra_timespec {
        __s32   tv_sec; /* seconds */
@@ -321,6 +323,22 @@ struct tegra_dc_ext_flip_3 {
        __u16 dirty_rect[4]; /* x,y,w,h for partial screen update. 0 ignores */
 };
 
+enum tegra_dc_ext_flip_data_type {
+       TEGRA_DC_EXT_FLIP_USER_DATA_NONE, /* dummy value - do not use */
+       TEGRA_DC_EXT_FLIP_USER_DATA_HDR_DATA,
+};
+
+/*
+ * Static Metadata for HDR
+ * This lets us specify which HDR static metadata to specify in the infoframe.
+ * Please see CEA 861.3 for more information.
+ */
+struct tegra_dc_ext_hdr {
+       __u8 eotf;
+       __u8 static_metadata_id;
+       __u8 static_metadata[24];
+};
+
 /* size of the this sturct is 32 bytes */
 struct tegra_dc_ext_flip_user_data {
        __u8 data_type;
@@ -330,7 +348,7 @@ struct tegra_dc_ext_flip_user_data {
        union { /* data to be packed into 26 bytes */
                __u8 data8[26];
                __u16 data16[13];
-               /*Add HDR data struct here*/
+               struct tegra_dc_ext_hdr hdr_info;
        };
 };