Loading drivers/video/fbdev/msm/mdss_hdmi_tx.c +97 −47 Original line number Diff line number Diff line Loading @@ -113,6 +113,7 @@ static void hdmi_tx_fps_work(struct work_struct *work); static int hdmi_tx_pinctrl_set_state(struct hdmi_tx_ctrl *hdmi_ctrl, enum hdmi_tx_power_module_type module, bool active); static void hdmi_panel_set_hdr_infoframe(struct hdmi_tx_ctrl *hdmi_ctrl); static void hdmi_panel_clear_hdr_infoframe(struct hdmi_tx_ctrl *hdmi_ctrl); static int hdmi_tx_audio_info_setup(struct platform_device *pdev, struct msm_ext_disp_audio_setup_params *params); static int hdmi_tx_get_audio_edid_blk(struct platform_device *pdev, Loading Loading @@ -1276,6 +1277,7 @@ static ssize_t hdmi_tx_sysfs_wta_hdr_stream(struct device *dev, { int ret = 0; struct hdmi_tx_ctrl *ctrl = NULL; u8 hdr_op; ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev); if (!ctrl) { Loading @@ -1296,36 +1298,43 @@ static ssize_t hdmi_tx_sysfs_wta_hdr_stream(struct device *dev, goto end; } memcpy(&ctrl->hdr_data, buf, sizeof(struct mdp_hdr_stream)); memcpy(&ctrl->hdr_ctrl, buf, sizeof(struct mdp_hdr_stream_ctrl)); pr_debug("%s: 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x\n", __func__, ctrl->hdr_data.eotf, ctrl->hdr_data.display_primaries_x[0], ctrl->hdr_data.display_primaries_y[0], ctrl->hdr_data.display_primaries_x[1], ctrl->hdr_data.display_primaries_y[1], ctrl->hdr_data.display_primaries_x[2], ctrl->hdr_data.display_primaries_y[2]); ctrl->hdr_ctrl.hdr_stream.eotf, ctrl->hdr_ctrl.hdr_stream.display_primaries_x[0], ctrl->hdr_ctrl.hdr_stream.display_primaries_y[0], ctrl->hdr_ctrl.hdr_stream.display_primaries_x[1], ctrl->hdr_ctrl.hdr_stream.display_primaries_y[1], ctrl->hdr_ctrl.hdr_stream.display_primaries_x[2], ctrl->hdr_ctrl.hdr_stream.display_primaries_y[2]); pr_debug("%s: 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x\n", __func__, ctrl->hdr_data.white_point_x, ctrl->hdr_data.white_point_y, ctrl->hdr_data.max_luminance, ctrl->hdr_data.min_luminance, ctrl->hdr_data.max_content_light_level, ctrl->hdr_data.max_average_light_level); ctrl->hdr_ctrl.hdr_stream.white_point_x, ctrl->hdr_ctrl.hdr_stream.white_point_y, ctrl->hdr_ctrl.hdr_stream.max_luminance, ctrl->hdr_ctrl.hdr_stream.min_luminance, ctrl->hdr_ctrl.hdr_stream.max_content_light_level, ctrl->hdr_ctrl.hdr_stream.max_average_light_level); pr_debug("%s: 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x\n", __func__, ctrl->hdr_data.pixel_encoding, ctrl->hdr_data.colorimetry, ctrl->hdr_data.range, ctrl->hdr_data.bits_per_component, ctrl->hdr_data.content_type); ctrl->hdr_ctrl.hdr_stream.pixel_encoding, ctrl->hdr_ctrl.hdr_stream.colorimetry, ctrl->hdr_ctrl.hdr_stream.range, ctrl->hdr_ctrl.hdr_stream.bits_per_component, ctrl->hdr_ctrl.hdr_stream.content_type); hdr_op = hdmi_hdr_get_ops(ctrl->curr_hdr_state, ctrl->hdr_ctrl.hdr_state); if (hdr_op == HDR_SEND_INFO) hdmi_panel_set_hdr_infoframe(ctrl); else if (hdr_op == HDR_CLEAR_INFO) hdmi_panel_clear_hdr_infoframe(ctrl); ctrl->curr_hdr_state = ctrl->hdr_ctrl.hdr_state; ret = strnlen(buf, PAGE_SIZE); end: Loading Loading @@ -2113,6 +2122,8 @@ static int hdmi_tx_init_features(struct hdmi_tx_ctrl *hdmi_ctrl, goto err; } /* reset HDR state */ hdmi_ctrl->curr_hdr_state = HDR_DISABLE; return 0; err: hdmi_tx_deinit_features(hdmi_ctrl, deinit_features); Loading Loading @@ -2871,11 +2882,12 @@ static void hdmi_panel_set_hdr_infoframe(struct hdmi_tx_ctrl *ctrl) packet_header = type_code | (version << 8) | (length << 16); DSS_REG_W(io, HDMI_GENERIC0_HDR, packet_header); packet_payload = (ctrl->hdr_data.eotf << 8); packet_payload = (ctrl->hdr_ctrl.hdr_stream.eotf << 8); if (hdmi_tx_metadata_type_one(ctrl)) { packet_payload |= (descriptor_id << 16) | (HDMI_GET_LSB(ctrl->hdr_data.display_primaries_x[0]) << 24); packet_payload |= (descriptor_id << 16) | (HDMI_GET_LSB(ctrl->hdr_ctrl.hdr_stream. display_primaries_x[0]) << 24); DSS_REG_W(io, HDMI_GENERIC0_0, packet_payload); } else { pr_debug("%s: Metadata Type 1 not supported\n", __func__); Loading @@ -2884,44 +2896,56 @@ static void hdmi_panel_set_hdr_infoframe(struct hdmi_tx_ctrl *ctrl) } packet_payload = (HDMI_GET_MSB(ctrl->hdr_data.display_primaries_x[0])) | (HDMI_GET_LSB(ctrl->hdr_data.display_primaries_y[0]) << 8) | (HDMI_GET_MSB(ctrl->hdr_data.display_primaries_y[0]) << 16) | (HDMI_GET_LSB(ctrl->hdr_data.display_primaries_x[1]) << 24); (HDMI_GET_MSB(ctrl->hdr_ctrl.hdr_stream.display_primaries_x[0])) | (HDMI_GET_LSB(ctrl->hdr_ctrl.hdr_stream. display_primaries_y[0]) << 8) | (HDMI_GET_MSB(ctrl->hdr_ctrl.hdr_stream. display_primaries_y[0]) << 16) | (HDMI_GET_LSB(ctrl->hdr_ctrl.hdr_stream. display_primaries_x[1]) << 24); DSS_REG_W(io, HDMI_GENERIC0_1, packet_payload); packet_payload = (HDMI_GET_MSB(ctrl->hdr_data.display_primaries_x[1])) | (HDMI_GET_LSB(ctrl->hdr_data.display_primaries_y[1]) << 8) | (HDMI_GET_MSB(ctrl->hdr_data.display_primaries_y[1]) << 16) | (HDMI_GET_LSB(ctrl->hdr_data.display_primaries_x[2]) << 24); (HDMI_GET_MSB(ctrl->hdr_ctrl.hdr_stream.display_primaries_x[1])) | (HDMI_GET_LSB(ctrl->hdr_ctrl.hdr_stream. display_primaries_y[1]) << 8) | (HDMI_GET_MSB(ctrl->hdr_ctrl.hdr_stream. display_primaries_y[1]) << 16) | (HDMI_GET_LSB(ctrl->hdr_ctrl.hdr_stream. display_primaries_x[2]) << 24); DSS_REG_W(io, HDMI_GENERIC0_2, packet_payload); packet_payload = (HDMI_GET_MSB(ctrl->hdr_data.display_primaries_x[2])) | (HDMI_GET_LSB(ctrl->hdr_data.display_primaries_y[2]) << 8) | (HDMI_GET_MSB(ctrl->hdr_data.display_primaries_y[2]) << 16) | (HDMI_GET_LSB(ctrl->hdr_data.white_point_x) << 24); (HDMI_GET_MSB(ctrl->hdr_ctrl.hdr_stream.display_primaries_x[2])) | (HDMI_GET_LSB(ctrl->hdr_ctrl.hdr_stream. display_primaries_y[2]) << 8) | (HDMI_GET_MSB(ctrl->hdr_ctrl.hdr_stream. display_primaries_y[2]) << 16) | (HDMI_GET_LSB(ctrl->hdr_ctrl.hdr_stream.white_point_x) << 24); DSS_REG_W(io, HDMI_GENERIC0_3, packet_payload); packet_payload = (HDMI_GET_MSB(ctrl->hdr_data.white_point_x)) | (HDMI_GET_LSB(ctrl->hdr_data.white_point_y) << 8) | (HDMI_GET_MSB(ctrl->hdr_data.white_point_y) << 16) | (HDMI_GET_LSB(ctrl->hdr_data.max_luminance) << 24); (HDMI_GET_MSB(ctrl->hdr_ctrl.hdr_stream.white_point_x)) | (HDMI_GET_LSB(ctrl->hdr_ctrl.hdr_stream.white_point_y) << 8) | (HDMI_GET_MSB(ctrl->hdr_ctrl.hdr_stream.white_point_y) << 16) | (HDMI_GET_LSB(ctrl->hdr_ctrl.hdr_stream.max_luminance) << 24); DSS_REG_W(io, HDMI_GENERIC0_4, packet_payload); packet_payload = (HDMI_GET_MSB(ctrl->hdr_data.max_luminance)) | (HDMI_GET_LSB(ctrl->hdr_data.min_luminance) << 8) | (HDMI_GET_MSB(ctrl->hdr_data.min_luminance) << 16) | (HDMI_GET_LSB(ctrl->hdr_data.max_content_light_level) << 24); (HDMI_GET_MSB(ctrl->hdr_ctrl.hdr_stream.max_luminance)) | (HDMI_GET_LSB(ctrl->hdr_ctrl.hdr_stream.min_luminance) << 8) | (HDMI_GET_MSB(ctrl->hdr_ctrl.hdr_stream.min_luminance) << 16) | (HDMI_GET_LSB(ctrl->hdr_ctrl.hdr_stream. max_content_light_level) << 24); DSS_REG_W(io, HDMI_GENERIC0_5, packet_payload); packet_payload = (HDMI_GET_MSB(ctrl->hdr_data.max_content_light_level)) | (HDMI_GET_LSB(ctrl->hdr_data.max_average_light_level) << 8) | (HDMI_GET_MSB(ctrl->hdr_data.max_average_light_level) << 16); (HDMI_GET_MSB(ctrl->hdr_ctrl.hdr_stream. max_content_light_level)) | (HDMI_GET_LSB(ctrl->hdr_ctrl.hdr_stream. max_average_light_level) << 8) | (HDMI_GET_MSB(ctrl->hdr_ctrl.hdr_stream. max_average_light_level) << 16); DSS_REG_W(io, HDMI_GENERIC0_6, packet_payload); enable_packet_control: Loading @@ -2936,6 +2960,32 @@ enable_packet_control: DSS_REG_W(io, HDMI_GEN_PKT_CTRL, packet_control); } static void hdmi_panel_clear_hdr_infoframe(struct hdmi_tx_ctrl *ctrl) { u32 packet_control = 0; struct dss_io_data *io = NULL; if (!ctrl) { pr_err("%s: invalid input\n", __func__); return; } if (!hdmi_tx_is_hdr_supported(ctrl)) { pr_err("%s: Sink does not support HDR\n", __func__); return; } io = &ctrl->pdata.io[HDMI_TX_CORE_IO]; if (!io->base) { pr_err("%s: core io not inititalized\n", __func__); return; } packet_control = DSS_REG_R_ND(io, HDMI_GEN_PKT_CTRL); packet_control &= ~HDMI_GEN_PKT_CTRL_CLR_MASK; DSS_REG_W(io, HDMI_GEN_PKT_CTRL, packet_control); } static int hdmi_tx_audio_info_setup(struct platform_device *pdev, struct msm_ext_disp_audio_setup_params *params) { Loading drivers/video/fbdev/msm/mdss_hdmi_tx.h +3 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include "mdss_hdmi_audio.h" #define MAX_SWITCH_NAME_SIZE 5 #define HDMI_GEN_PKT_CTRL_CLR_MASK 0x7 enum hdmi_tx_io_type { HDMI_TX_CORE_IO, Loading Loading @@ -90,7 +91,7 @@ struct hdmi_tx_ctrl { struct msm_ext_disp_audio_setup_params audio_params; struct msm_ext_disp_init_data ext_audio_data; struct work_struct fps_work; struct mdp_hdr_stream hdr_data; struct mdp_hdr_stream_ctrl hdr_ctrl; spinlock_t hpd_state_lock; Loading @@ -116,6 +117,7 @@ struct hdmi_tx_ctrl { u8 hdcp_status; u8 spd_vendor_name[9]; u8 spd_product_description[17]; u8 curr_hdr_state; bool hdcp_feature_on; bool hpd_disabled; Loading drivers/video/fbdev/msm/mdss_hdmi_util.c +49 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include <linux/io.h> #include <linux/delay.h> #include <linux/msm_mdp.h> #include <linux/msm_mdp_ext.h> #include "mdss_hdmi_util.h" #define RESOLUTION_NAME_STR_LEN 30 Loading Loading @@ -1811,3 +1812,51 @@ int hdmi_hdcp2p2_ddc_read_rxstatus(struct hdmi_tx_ddc_ctrl *ctrl) return rc; } u8 hdmi_hdr_get_ops(u8 curr_state, u8 new_state) { /** There could be 3 valid state transitions: * 1. HDR_DISABLE -> HDR_ENABLE * * In this transition, we shall start sending * HDR metadata with metadata from the HDR clip * * 2. HDR_ENABLE -> HDR_RESET * * In this transition, we will keep sending * HDR metadata but with EOTF and metadata as 0 * * 3. HDR_RESET -> HDR_ENABLE * * In this transition, we will start sending * HDR metadata with metadata from the HDR clip * * 4. HDR_RESET -> HDR_DISABLE * * In this transition, we will stop sending * metadata to the sink and clear PKT_CTRL register * bits. */ if ((curr_state == HDR_DISABLE) && (new_state == HDR_ENABLE)) { pr_debug("State changed HDR_DISABLE ---> HDR_ENABLE\n"); return HDR_SEND_INFO; } else if ((curr_state == HDR_ENABLE) && (new_state == HDR_RESET)) { pr_debug("State changed HDR_ENABLE ---> HDR_RESET\n"); return HDR_SEND_INFO; } else if ((curr_state == HDR_RESET) && (new_state == HDR_ENABLE)) { pr_debug("State changed HDR_RESET ---> HDR_ENABLE\n"); return HDR_SEND_INFO; } else if ((curr_state == HDR_RESET) && (new_state == HDR_DISABLE)) { pr_debug("State changed HDR_RESET ---> HDR_DISABLE\n"); return HDR_CLEAR_INFO; } pr_debug("Unsupported OR no state change\n"); return HDR_UNSUPPORTED_OP; } drivers/video/fbdev/msm/mdss_hdmi_util.h +8 −2 Original line number Diff line number Diff line /* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2010-2017, The Linux Foundation. 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 version 2 and Loading Loading @@ -425,6 +425,12 @@ enum hdmi_tx_hdcp2p2_rxstatus_intr_mask { RXSTATUS_REAUTH_REQ = BIT(14), }; enum hdmi_hdr_op { HDR_UNSUPPORTED_OP, HDR_SEND_INFO, HDR_CLEAR_INFO }; struct hdmi_tx_hdcp2p2_ddc_data { enum hdmi_tx_hdcp2p2_rxstatus_intr_mask intr_mask; u32 timeout_ms; Loading Loading @@ -518,5 +524,5 @@ void hdmi_hdcp2p2_ddc_disable(struct hdmi_tx_ddc_ctrl *ctrl); int hdmi_hdcp2p2_ddc_read_rxstatus(struct hdmi_tx_ddc_ctrl *ctrl); int hdmi_utils_get_timeout_in_hysnc(struct msm_hdmi_mode_timing_info *timing, u32 timeout_ms); u8 hdmi_hdr_get_ops(u8 curr_state, u8 new_state); #endif /* __HDMI_UTIL_H__ */ include/uapi/linux/msm_mdp_ext.h +22 −0 Original line number Diff line number Diff line Loading @@ -821,4 +821,26 @@ struct mdp_hdr_stream { uint32_t content_type; uint32_t reserved[5]; }; /* hdr hdmi state takes possible values of 1, 2 and 4 respectively */ #define HDR_ENABLE (1 << 0) #define HDR_DISABLE (1 << 1) #define HDR_RESET (1 << 2) /* * HDR Control * This encapsulates the HDR metadata as well as a state control * for the HDR metadata as required by the HDMI spec to send the * relevant metadata depending on the state of the HDR playback. * hdr_state: Controls HDR state, takes values HDR_ENABLE, HDR_DISABLE * and HDR_RESET. * hdr_meta: Metadata sent by the userspace for the HDR clip. */ #define DRM_MSM_EXT_PANEL_HDR_CTRL struct mdp_hdr_stream_ctrl { __u8 hdr_state; /* HDR state */ struct mdp_hdr_stream hdr_stream; /* HDR metadata */ }; #endif Loading
drivers/video/fbdev/msm/mdss_hdmi_tx.c +97 −47 Original line number Diff line number Diff line Loading @@ -113,6 +113,7 @@ static void hdmi_tx_fps_work(struct work_struct *work); static int hdmi_tx_pinctrl_set_state(struct hdmi_tx_ctrl *hdmi_ctrl, enum hdmi_tx_power_module_type module, bool active); static void hdmi_panel_set_hdr_infoframe(struct hdmi_tx_ctrl *hdmi_ctrl); static void hdmi_panel_clear_hdr_infoframe(struct hdmi_tx_ctrl *hdmi_ctrl); static int hdmi_tx_audio_info_setup(struct platform_device *pdev, struct msm_ext_disp_audio_setup_params *params); static int hdmi_tx_get_audio_edid_blk(struct platform_device *pdev, Loading Loading @@ -1276,6 +1277,7 @@ static ssize_t hdmi_tx_sysfs_wta_hdr_stream(struct device *dev, { int ret = 0; struct hdmi_tx_ctrl *ctrl = NULL; u8 hdr_op; ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev); if (!ctrl) { Loading @@ -1296,36 +1298,43 @@ static ssize_t hdmi_tx_sysfs_wta_hdr_stream(struct device *dev, goto end; } memcpy(&ctrl->hdr_data, buf, sizeof(struct mdp_hdr_stream)); memcpy(&ctrl->hdr_ctrl, buf, sizeof(struct mdp_hdr_stream_ctrl)); pr_debug("%s: 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x\n", __func__, ctrl->hdr_data.eotf, ctrl->hdr_data.display_primaries_x[0], ctrl->hdr_data.display_primaries_y[0], ctrl->hdr_data.display_primaries_x[1], ctrl->hdr_data.display_primaries_y[1], ctrl->hdr_data.display_primaries_x[2], ctrl->hdr_data.display_primaries_y[2]); ctrl->hdr_ctrl.hdr_stream.eotf, ctrl->hdr_ctrl.hdr_stream.display_primaries_x[0], ctrl->hdr_ctrl.hdr_stream.display_primaries_y[0], ctrl->hdr_ctrl.hdr_stream.display_primaries_x[1], ctrl->hdr_ctrl.hdr_stream.display_primaries_y[1], ctrl->hdr_ctrl.hdr_stream.display_primaries_x[2], ctrl->hdr_ctrl.hdr_stream.display_primaries_y[2]); pr_debug("%s: 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x\n", __func__, ctrl->hdr_data.white_point_x, ctrl->hdr_data.white_point_y, ctrl->hdr_data.max_luminance, ctrl->hdr_data.min_luminance, ctrl->hdr_data.max_content_light_level, ctrl->hdr_data.max_average_light_level); ctrl->hdr_ctrl.hdr_stream.white_point_x, ctrl->hdr_ctrl.hdr_stream.white_point_y, ctrl->hdr_ctrl.hdr_stream.max_luminance, ctrl->hdr_ctrl.hdr_stream.min_luminance, ctrl->hdr_ctrl.hdr_stream.max_content_light_level, ctrl->hdr_ctrl.hdr_stream.max_average_light_level); pr_debug("%s: 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x\n", __func__, ctrl->hdr_data.pixel_encoding, ctrl->hdr_data.colorimetry, ctrl->hdr_data.range, ctrl->hdr_data.bits_per_component, ctrl->hdr_data.content_type); ctrl->hdr_ctrl.hdr_stream.pixel_encoding, ctrl->hdr_ctrl.hdr_stream.colorimetry, ctrl->hdr_ctrl.hdr_stream.range, ctrl->hdr_ctrl.hdr_stream.bits_per_component, ctrl->hdr_ctrl.hdr_stream.content_type); hdr_op = hdmi_hdr_get_ops(ctrl->curr_hdr_state, ctrl->hdr_ctrl.hdr_state); if (hdr_op == HDR_SEND_INFO) hdmi_panel_set_hdr_infoframe(ctrl); else if (hdr_op == HDR_CLEAR_INFO) hdmi_panel_clear_hdr_infoframe(ctrl); ctrl->curr_hdr_state = ctrl->hdr_ctrl.hdr_state; ret = strnlen(buf, PAGE_SIZE); end: Loading Loading @@ -2113,6 +2122,8 @@ static int hdmi_tx_init_features(struct hdmi_tx_ctrl *hdmi_ctrl, goto err; } /* reset HDR state */ hdmi_ctrl->curr_hdr_state = HDR_DISABLE; return 0; err: hdmi_tx_deinit_features(hdmi_ctrl, deinit_features); Loading Loading @@ -2871,11 +2882,12 @@ static void hdmi_panel_set_hdr_infoframe(struct hdmi_tx_ctrl *ctrl) packet_header = type_code | (version << 8) | (length << 16); DSS_REG_W(io, HDMI_GENERIC0_HDR, packet_header); packet_payload = (ctrl->hdr_data.eotf << 8); packet_payload = (ctrl->hdr_ctrl.hdr_stream.eotf << 8); if (hdmi_tx_metadata_type_one(ctrl)) { packet_payload |= (descriptor_id << 16) | (HDMI_GET_LSB(ctrl->hdr_data.display_primaries_x[0]) << 24); packet_payload |= (descriptor_id << 16) | (HDMI_GET_LSB(ctrl->hdr_ctrl.hdr_stream. display_primaries_x[0]) << 24); DSS_REG_W(io, HDMI_GENERIC0_0, packet_payload); } else { pr_debug("%s: Metadata Type 1 not supported\n", __func__); Loading @@ -2884,44 +2896,56 @@ static void hdmi_panel_set_hdr_infoframe(struct hdmi_tx_ctrl *ctrl) } packet_payload = (HDMI_GET_MSB(ctrl->hdr_data.display_primaries_x[0])) | (HDMI_GET_LSB(ctrl->hdr_data.display_primaries_y[0]) << 8) | (HDMI_GET_MSB(ctrl->hdr_data.display_primaries_y[0]) << 16) | (HDMI_GET_LSB(ctrl->hdr_data.display_primaries_x[1]) << 24); (HDMI_GET_MSB(ctrl->hdr_ctrl.hdr_stream.display_primaries_x[0])) | (HDMI_GET_LSB(ctrl->hdr_ctrl.hdr_stream. display_primaries_y[0]) << 8) | (HDMI_GET_MSB(ctrl->hdr_ctrl.hdr_stream. display_primaries_y[0]) << 16) | (HDMI_GET_LSB(ctrl->hdr_ctrl.hdr_stream. display_primaries_x[1]) << 24); DSS_REG_W(io, HDMI_GENERIC0_1, packet_payload); packet_payload = (HDMI_GET_MSB(ctrl->hdr_data.display_primaries_x[1])) | (HDMI_GET_LSB(ctrl->hdr_data.display_primaries_y[1]) << 8) | (HDMI_GET_MSB(ctrl->hdr_data.display_primaries_y[1]) << 16) | (HDMI_GET_LSB(ctrl->hdr_data.display_primaries_x[2]) << 24); (HDMI_GET_MSB(ctrl->hdr_ctrl.hdr_stream.display_primaries_x[1])) | (HDMI_GET_LSB(ctrl->hdr_ctrl.hdr_stream. display_primaries_y[1]) << 8) | (HDMI_GET_MSB(ctrl->hdr_ctrl.hdr_stream. display_primaries_y[1]) << 16) | (HDMI_GET_LSB(ctrl->hdr_ctrl.hdr_stream. display_primaries_x[2]) << 24); DSS_REG_W(io, HDMI_GENERIC0_2, packet_payload); packet_payload = (HDMI_GET_MSB(ctrl->hdr_data.display_primaries_x[2])) | (HDMI_GET_LSB(ctrl->hdr_data.display_primaries_y[2]) << 8) | (HDMI_GET_MSB(ctrl->hdr_data.display_primaries_y[2]) << 16) | (HDMI_GET_LSB(ctrl->hdr_data.white_point_x) << 24); (HDMI_GET_MSB(ctrl->hdr_ctrl.hdr_stream.display_primaries_x[2])) | (HDMI_GET_LSB(ctrl->hdr_ctrl.hdr_stream. display_primaries_y[2]) << 8) | (HDMI_GET_MSB(ctrl->hdr_ctrl.hdr_stream. display_primaries_y[2]) << 16) | (HDMI_GET_LSB(ctrl->hdr_ctrl.hdr_stream.white_point_x) << 24); DSS_REG_W(io, HDMI_GENERIC0_3, packet_payload); packet_payload = (HDMI_GET_MSB(ctrl->hdr_data.white_point_x)) | (HDMI_GET_LSB(ctrl->hdr_data.white_point_y) << 8) | (HDMI_GET_MSB(ctrl->hdr_data.white_point_y) << 16) | (HDMI_GET_LSB(ctrl->hdr_data.max_luminance) << 24); (HDMI_GET_MSB(ctrl->hdr_ctrl.hdr_stream.white_point_x)) | (HDMI_GET_LSB(ctrl->hdr_ctrl.hdr_stream.white_point_y) << 8) | (HDMI_GET_MSB(ctrl->hdr_ctrl.hdr_stream.white_point_y) << 16) | (HDMI_GET_LSB(ctrl->hdr_ctrl.hdr_stream.max_luminance) << 24); DSS_REG_W(io, HDMI_GENERIC0_4, packet_payload); packet_payload = (HDMI_GET_MSB(ctrl->hdr_data.max_luminance)) | (HDMI_GET_LSB(ctrl->hdr_data.min_luminance) << 8) | (HDMI_GET_MSB(ctrl->hdr_data.min_luminance) << 16) | (HDMI_GET_LSB(ctrl->hdr_data.max_content_light_level) << 24); (HDMI_GET_MSB(ctrl->hdr_ctrl.hdr_stream.max_luminance)) | (HDMI_GET_LSB(ctrl->hdr_ctrl.hdr_stream.min_luminance) << 8) | (HDMI_GET_MSB(ctrl->hdr_ctrl.hdr_stream.min_luminance) << 16) | (HDMI_GET_LSB(ctrl->hdr_ctrl.hdr_stream. max_content_light_level) << 24); DSS_REG_W(io, HDMI_GENERIC0_5, packet_payload); packet_payload = (HDMI_GET_MSB(ctrl->hdr_data.max_content_light_level)) | (HDMI_GET_LSB(ctrl->hdr_data.max_average_light_level) << 8) | (HDMI_GET_MSB(ctrl->hdr_data.max_average_light_level) << 16); (HDMI_GET_MSB(ctrl->hdr_ctrl.hdr_stream. max_content_light_level)) | (HDMI_GET_LSB(ctrl->hdr_ctrl.hdr_stream. max_average_light_level) << 8) | (HDMI_GET_MSB(ctrl->hdr_ctrl.hdr_stream. max_average_light_level) << 16); DSS_REG_W(io, HDMI_GENERIC0_6, packet_payload); enable_packet_control: Loading @@ -2936,6 +2960,32 @@ enable_packet_control: DSS_REG_W(io, HDMI_GEN_PKT_CTRL, packet_control); } static void hdmi_panel_clear_hdr_infoframe(struct hdmi_tx_ctrl *ctrl) { u32 packet_control = 0; struct dss_io_data *io = NULL; if (!ctrl) { pr_err("%s: invalid input\n", __func__); return; } if (!hdmi_tx_is_hdr_supported(ctrl)) { pr_err("%s: Sink does not support HDR\n", __func__); return; } io = &ctrl->pdata.io[HDMI_TX_CORE_IO]; if (!io->base) { pr_err("%s: core io not inititalized\n", __func__); return; } packet_control = DSS_REG_R_ND(io, HDMI_GEN_PKT_CTRL); packet_control &= ~HDMI_GEN_PKT_CTRL_CLR_MASK; DSS_REG_W(io, HDMI_GEN_PKT_CTRL, packet_control); } static int hdmi_tx_audio_info_setup(struct platform_device *pdev, struct msm_ext_disp_audio_setup_params *params) { Loading
drivers/video/fbdev/msm/mdss_hdmi_tx.h +3 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include "mdss_hdmi_audio.h" #define MAX_SWITCH_NAME_SIZE 5 #define HDMI_GEN_PKT_CTRL_CLR_MASK 0x7 enum hdmi_tx_io_type { HDMI_TX_CORE_IO, Loading Loading @@ -90,7 +91,7 @@ struct hdmi_tx_ctrl { struct msm_ext_disp_audio_setup_params audio_params; struct msm_ext_disp_init_data ext_audio_data; struct work_struct fps_work; struct mdp_hdr_stream hdr_data; struct mdp_hdr_stream_ctrl hdr_ctrl; spinlock_t hpd_state_lock; Loading @@ -116,6 +117,7 @@ struct hdmi_tx_ctrl { u8 hdcp_status; u8 spd_vendor_name[9]; u8 spd_product_description[17]; u8 curr_hdr_state; bool hdcp_feature_on; bool hpd_disabled; Loading
drivers/video/fbdev/msm/mdss_hdmi_util.c +49 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include <linux/io.h> #include <linux/delay.h> #include <linux/msm_mdp.h> #include <linux/msm_mdp_ext.h> #include "mdss_hdmi_util.h" #define RESOLUTION_NAME_STR_LEN 30 Loading Loading @@ -1811,3 +1812,51 @@ int hdmi_hdcp2p2_ddc_read_rxstatus(struct hdmi_tx_ddc_ctrl *ctrl) return rc; } u8 hdmi_hdr_get_ops(u8 curr_state, u8 new_state) { /** There could be 3 valid state transitions: * 1. HDR_DISABLE -> HDR_ENABLE * * In this transition, we shall start sending * HDR metadata with metadata from the HDR clip * * 2. HDR_ENABLE -> HDR_RESET * * In this transition, we will keep sending * HDR metadata but with EOTF and metadata as 0 * * 3. HDR_RESET -> HDR_ENABLE * * In this transition, we will start sending * HDR metadata with metadata from the HDR clip * * 4. HDR_RESET -> HDR_DISABLE * * In this transition, we will stop sending * metadata to the sink and clear PKT_CTRL register * bits. */ if ((curr_state == HDR_DISABLE) && (new_state == HDR_ENABLE)) { pr_debug("State changed HDR_DISABLE ---> HDR_ENABLE\n"); return HDR_SEND_INFO; } else if ((curr_state == HDR_ENABLE) && (new_state == HDR_RESET)) { pr_debug("State changed HDR_ENABLE ---> HDR_RESET\n"); return HDR_SEND_INFO; } else if ((curr_state == HDR_RESET) && (new_state == HDR_ENABLE)) { pr_debug("State changed HDR_RESET ---> HDR_ENABLE\n"); return HDR_SEND_INFO; } else if ((curr_state == HDR_RESET) && (new_state == HDR_DISABLE)) { pr_debug("State changed HDR_RESET ---> HDR_DISABLE\n"); return HDR_CLEAR_INFO; } pr_debug("Unsupported OR no state change\n"); return HDR_UNSUPPORTED_OP; }
drivers/video/fbdev/msm/mdss_hdmi_util.h +8 −2 Original line number Diff line number Diff line /* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2010-2017, The Linux Foundation. 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 version 2 and Loading Loading @@ -425,6 +425,12 @@ enum hdmi_tx_hdcp2p2_rxstatus_intr_mask { RXSTATUS_REAUTH_REQ = BIT(14), }; enum hdmi_hdr_op { HDR_UNSUPPORTED_OP, HDR_SEND_INFO, HDR_CLEAR_INFO }; struct hdmi_tx_hdcp2p2_ddc_data { enum hdmi_tx_hdcp2p2_rxstatus_intr_mask intr_mask; u32 timeout_ms; Loading Loading @@ -518,5 +524,5 @@ void hdmi_hdcp2p2_ddc_disable(struct hdmi_tx_ddc_ctrl *ctrl); int hdmi_hdcp2p2_ddc_read_rxstatus(struct hdmi_tx_ddc_ctrl *ctrl); int hdmi_utils_get_timeout_in_hysnc(struct msm_hdmi_mode_timing_info *timing, u32 timeout_ms); u8 hdmi_hdr_get_ops(u8 curr_state, u8 new_state); #endif /* __HDMI_UTIL_H__ */
include/uapi/linux/msm_mdp_ext.h +22 −0 Original line number Diff line number Diff line Loading @@ -821,4 +821,26 @@ struct mdp_hdr_stream { uint32_t content_type; uint32_t reserved[5]; }; /* hdr hdmi state takes possible values of 1, 2 and 4 respectively */ #define HDR_ENABLE (1 << 0) #define HDR_DISABLE (1 << 1) #define HDR_RESET (1 << 2) /* * HDR Control * This encapsulates the HDR metadata as well as a state control * for the HDR metadata as required by the HDMI spec to send the * relevant metadata depending on the state of the HDR playback. * hdr_state: Controls HDR state, takes values HDR_ENABLE, HDR_DISABLE * and HDR_RESET. * hdr_meta: Metadata sent by the userspace for the HDR clip. */ #define DRM_MSM_EXT_PANEL_HDR_CTRL struct mdp_hdr_stream_ctrl { __u8 hdr_state; /* HDR state */ struct mdp_hdr_stream hdr_stream; /* HDR metadata */ }; #endif