Loading drivers/video/msm/mdss/mdss_hdmi_edid.c +28 −5 Original line number Diff line number Diff line Loading @@ -91,7 +91,7 @@ enum extended_data_block_types { struct disp_mode_info { u32 video_format; u32 video_3d_format; u32 video_3d_format; /* Flags like SIDE_BY_SIDE_HALF*/ bool rgb_support; bool y420_support; }; Loading Loading @@ -615,7 +615,9 @@ static ssize_t hdmi_edid_sysfs_rda_3d_modes(struct device *dev, edid_ctrl->sink_data.disp_mode_list; for (i = 0; i < edid_ctrl->sink_data.num_of_elements; i++) { ret = hdmi_get_video_3d_fmt_2string( if (!video_mode[i].video_3d_format) continue; hdmi_get_video_3d_fmt_2string( video_mode[i].video_3d_format, buff_3d, sizeof(buff_3d)); Loading @@ -628,9 +630,6 @@ static ssize_t hdmi_edid_sysfs_rda_3d_modes(struct device *dev, "%d=%s", video_mode[i].video_format, buff_3d); } } else { ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%d", edid_ctrl->video_resolution); } DEV_DBG("%s: '%s'\n", __func__, buf); Loading Loading @@ -2254,6 +2253,30 @@ u32 hdmi_edid_get_sink_mode(void *input) return edid_ctrl->sink_mode; } /* hdmi_edid_get_sink_mode */ bool hdmi_edid_is_s3d_mode_supported(void *input, u32 video_mode, u32 s3d_mode) { int i; bool ret = false; struct hdmi_edid_ctrl *edid_ctrl = (struct hdmi_edid_ctrl *)input; struct hdmi_edid_sink_data *sink_data; sink_data = &edid_ctrl->sink_data; for (i = 0; i < sink_data->num_of_elements; ++i) { if (sink_data->disp_mode_list[i].video_format != video_mode) continue; if (sink_data->disp_mode_list[i].video_3d_format & (1 << s3d_mode)) ret = true; else DEV_DBG("%s: return false: vic=%d caps=%x s3d=%d\n", __func__, video_mode, sink_data->disp_mode_list[i].video_3d_format, s3d_mode); break; } return ret; } bool hdmi_edid_get_scdc_support(void *input) { struct hdmi_edid_ctrl *edid_ctrl = input; Loading drivers/video/msm/mdss/mdss_hdmi_edid.h +2 −0 Original line number Diff line number Diff line Loading @@ -40,5 +40,7 @@ void hdmi_edid_set_video_resolution(void *edid_ctrl, u32 resolution, bool reset); void hdmi_edid_deinit(void *edid_ctrl); void *hdmi_edid_init(struct hdmi_edid_init_data *init_data); bool hdmi_edid_is_s3d_mode_supported(void *input, u32 video_mode, u32 s3d_mode); #endif /* __HDMI_EDID_H__ */ drivers/video/msm/mdss/mdss_hdmi_tx.c +109 −26 Original line number Diff line number Diff line Loading @@ -199,6 +199,8 @@ static int hdmi_tx_enable_power(struct hdmi_tx_ctrl *hdmi_ctrl, enum hdmi_tx_power_module_type module, int enable); static int hdmi_tx_audio_setup(struct hdmi_tx_ctrl *hdmi_ctrl); static int hdmi_tx_setup_tmds_clk_rate(struct hdmi_tx_ctrl *hdmi_ctrl); static void hdmi_tx_set_vendor_specific_infoframe( struct hdmi_tx_ctrl *hdmi_ctrl); static struct mdss_hw hdmi_tx_hw = { .hw_ndx = MDSS_HW_HDMI, Loading Loading @@ -1059,6 +1061,66 @@ static ssize_t hdmi_tx_sysfs_wta_avi_cn_bits(struct device *dev, return ret; } /* hdmi_tx_sysfs_wta_cn_bits */ static ssize_t hdmi_tx_sysfs_wta_s3d_mode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int rc, s3d_mode; ssize_t ret = strnlen(buf, PAGE_SIZE); struct hdmi_tx_ctrl *hdmi_ctrl = NULL; hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev); if (!hdmi_ctrl) { DEV_ERR("%s: invalid input\n", __func__); return -EINVAL; } rc = kstrtoint(buf, 10, &s3d_mode); if (rc) { DEV_ERR("%s: kstrtoint failed. rc=%d\n", __func__, rc); return rc; } if (s3d_mode < HDMI_S3D_NONE || s3d_mode >= HDMI_S3D_MAX) { DEV_ERR("%s: invalid s3d mode = %d\n", __func__, s3d_mode); return -EINVAL; } if (s3d_mode > HDMI_S3D_NONE && !hdmi_edid_is_s3d_mode_supported( hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID], hdmi_ctrl->vid_cfg.vic, s3d_mode)) { DEV_ERR("%s: s3d mode not supported in current video mode\n", __func__); return -EPERM; } hdmi_ctrl->s3d_mode = s3d_mode; hdmi_tx_set_vendor_specific_infoframe(hdmi_ctrl); DEV_DBG("%s: %d\n", __func__, hdmi_ctrl->s3d_mode); return ret; } static ssize_t hdmi_tx_sysfs_rda_s3d_mode(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t ret; struct hdmi_tx_ctrl *hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev); if (!hdmi_ctrl) { DEV_ERR("%s: invalid input\n", __func__); return -EINVAL; } ret = snprintf(buf, PAGE_SIZE, "%d\n", hdmi_ctrl->s3d_mode); DEV_DBG("%s: '%d'\n", __func__, hdmi_ctrl->s3d_mode); return ret; } static DEVICE_ATTR(connected, S_IRUGO, hdmi_tx_sysfs_rda_connected, NULL); static DEVICE_ATTR(hdmi_audio_cb, S_IWUSR, NULL, hdmi_tx_sysfs_wta_audio_cb); static DEVICE_ATTR(video_mode, S_IRUGO, hdmi_tx_sysfs_rda_video_mode, NULL); Loading @@ -1071,6 +1133,8 @@ static DEVICE_ATTR(product_description, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_wta_product_description); static DEVICE_ATTR(avi_itc, S_IWUSR, NULL, hdmi_tx_sysfs_wta_avi_itc); static DEVICE_ATTR(avi_cn0_1, S_IWUSR, NULL, hdmi_tx_sysfs_wta_avi_cn_bits); static DEVICE_ATTR(s3d_mode, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_rda_s3d_mode, hdmi_tx_sysfs_wta_s3d_mode); static struct attribute *hdmi_tx_fs_attrs[] = { &dev_attr_connected.attr, Loading @@ -1081,6 +1145,7 @@ static struct attribute *hdmi_tx_fs_attrs[] = { &dev_attr_product_description.attr, &dev_attr_avi_itc.attr, &dev_attr_avi_cn0_1.attr, &dev_attr_s3d_mode.attr, NULL, }; static struct attribute_group hdmi_tx_fs_attrs_group = { Loading Loading @@ -2075,14 +2140,13 @@ static void hdmi_tx_set_avi_infoframe(struct hdmi_tx_ctrl *hdmi_ctrl) DSS_REG_W(io, HDMI_INFOFRAME_CTRL1, reg_val); } /* hdmi_tx_set_avi_infoframe */ /* todo: add 3D support */ void hdmi_tx_set_vendor_specific_infoframe( static void hdmi_tx_set_vendor_specific_infoframe( struct hdmi_tx_ctrl *hdmi_ctrl) { int i; u8 vs_iframe[9]; /* two header + length + 6 data */ u32 sum, reg_val; u32 hdmi_vic, hdmi_video_format; u32 hdmi_vic, hdmi_video_format, s3d_struct = 0; struct dss_io_data *io = NULL; if (!hdmi_ctrl) { Loading @@ -2108,6 +2172,26 @@ void hdmi_tx_set_vendor_specific_infoframe( vs_iframe[5] = 0x0C; vs_iframe[6] = 0x00; if ((hdmi_ctrl->s3d_mode != HDMI_S3D_NONE) && hdmi_edid_is_s3d_mode_supported( hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID], hdmi_ctrl->vid_cfg.vic, hdmi_ctrl->s3d_mode)) { switch (hdmi_ctrl->s3d_mode) { case HDMI_S3D_SIDE_BY_SIDE: s3d_struct = 0x8; break; case HDMI_S3D_TOP_AND_BOTTOM: s3d_struct = 0x6; break; default: s3d_struct = 0; } hdmi_video_format = 0x2; hdmi_vic = 0; /* PB5: 3D_Structure[7:4], Reserved[3:0] */ vs_iframe[8] = s3d_struct << 4; } else { hdmi_video_format = 0x1; switch (hdmi_ctrl->vid_cfg.vic) { case HDMI_EVFRMT_3840x2160p30_16_9: Loading @@ -2126,13 +2210,12 @@ void hdmi_tx_set_vendor_specific_infoframe( hdmi_video_format = 0x0; hdmi_vic = 0x0; } /* PB5: HDMI_VIC */ vs_iframe[8] = hdmi_vic; } /* PB4: HDMI Video Format[7:5], Reserved[4:0] */ vs_iframe[7] = (hdmi_video_format << 5) & 0xE0; /* PB5: HDMI_VIC or 3D_Structure[7:4], Reserved[3:0] */ vs_iframe[8] = hdmi_vic; /* compute checksum */ sum = 0; for (i = 0; i < 9; i++) Loading @@ -2142,7 +2225,7 @@ void hdmi_tx_set_vendor_specific_infoframe( sum = 256 - sum; vs_iframe[3] = (u8)sum; reg_val = (hdmi_vic << 16) | (vs_iframe[3] << 8) | reg_val = (s3d_struct << 24) | (hdmi_vic << 16) | (vs_iframe[3] << 8) | (hdmi_video_format << 5) | vs_iframe[2]; DSS_REG_W(io, HDMI_VENSPEC_INFO0, reg_val); Loading drivers/video/msm/mdss/mdss_hdmi_tx.h +1 −0 Original line number Diff line number Diff line Loading @@ -189,6 +189,7 @@ struct hdmi_tx_ctrl { u8 *edid_buf; u32 edid_buf_size; u32 s3d_mode; }; #endif /* __MDSS_HDMI_TX_H__ */ drivers/video/msm/mdss/mdss_hdmi_util.h +3 −3 Original line number Diff line number Diff line Loading @@ -258,9 +258,9 @@ /* SEC_CTRL version that supports HDCP SEL */ #define HDCP_SEL_MIN_SEC_VERSION (0x50010000) #define TOP_AND_BOTTOM 0x10 #define FRAME_PACKING 0x20 #define SIDE_BY_SIDE_HALF 0x40 #define TOP_AND_BOTTOM (1 << HDMI_S3D_TOP_AND_BOTTOM) #define FRAME_PACKING (1 << HDMI_S3D_FRAME_PACKING) #define SIDE_BY_SIDE_HALF (1 << HDMI_S3D_SIDE_BY_SIDE) #define LPASS_LPAIF_RDDMA_CTL0 (0xFE152000) #define LPASS_LPAIF_RDDMA_PER_CNT0 (0x00000014) Loading Loading
drivers/video/msm/mdss/mdss_hdmi_edid.c +28 −5 Original line number Diff line number Diff line Loading @@ -91,7 +91,7 @@ enum extended_data_block_types { struct disp_mode_info { u32 video_format; u32 video_3d_format; u32 video_3d_format; /* Flags like SIDE_BY_SIDE_HALF*/ bool rgb_support; bool y420_support; }; Loading Loading @@ -615,7 +615,9 @@ static ssize_t hdmi_edid_sysfs_rda_3d_modes(struct device *dev, edid_ctrl->sink_data.disp_mode_list; for (i = 0; i < edid_ctrl->sink_data.num_of_elements; i++) { ret = hdmi_get_video_3d_fmt_2string( if (!video_mode[i].video_3d_format) continue; hdmi_get_video_3d_fmt_2string( video_mode[i].video_3d_format, buff_3d, sizeof(buff_3d)); Loading @@ -628,9 +630,6 @@ static ssize_t hdmi_edid_sysfs_rda_3d_modes(struct device *dev, "%d=%s", video_mode[i].video_format, buff_3d); } } else { ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%d", edid_ctrl->video_resolution); } DEV_DBG("%s: '%s'\n", __func__, buf); Loading Loading @@ -2254,6 +2253,30 @@ u32 hdmi_edid_get_sink_mode(void *input) return edid_ctrl->sink_mode; } /* hdmi_edid_get_sink_mode */ bool hdmi_edid_is_s3d_mode_supported(void *input, u32 video_mode, u32 s3d_mode) { int i; bool ret = false; struct hdmi_edid_ctrl *edid_ctrl = (struct hdmi_edid_ctrl *)input; struct hdmi_edid_sink_data *sink_data; sink_data = &edid_ctrl->sink_data; for (i = 0; i < sink_data->num_of_elements; ++i) { if (sink_data->disp_mode_list[i].video_format != video_mode) continue; if (sink_data->disp_mode_list[i].video_3d_format & (1 << s3d_mode)) ret = true; else DEV_DBG("%s: return false: vic=%d caps=%x s3d=%d\n", __func__, video_mode, sink_data->disp_mode_list[i].video_3d_format, s3d_mode); break; } return ret; } bool hdmi_edid_get_scdc_support(void *input) { struct hdmi_edid_ctrl *edid_ctrl = input; Loading
drivers/video/msm/mdss/mdss_hdmi_edid.h +2 −0 Original line number Diff line number Diff line Loading @@ -40,5 +40,7 @@ void hdmi_edid_set_video_resolution(void *edid_ctrl, u32 resolution, bool reset); void hdmi_edid_deinit(void *edid_ctrl); void *hdmi_edid_init(struct hdmi_edid_init_data *init_data); bool hdmi_edid_is_s3d_mode_supported(void *input, u32 video_mode, u32 s3d_mode); #endif /* __HDMI_EDID_H__ */
drivers/video/msm/mdss/mdss_hdmi_tx.c +109 −26 Original line number Diff line number Diff line Loading @@ -199,6 +199,8 @@ static int hdmi_tx_enable_power(struct hdmi_tx_ctrl *hdmi_ctrl, enum hdmi_tx_power_module_type module, int enable); static int hdmi_tx_audio_setup(struct hdmi_tx_ctrl *hdmi_ctrl); static int hdmi_tx_setup_tmds_clk_rate(struct hdmi_tx_ctrl *hdmi_ctrl); static void hdmi_tx_set_vendor_specific_infoframe( struct hdmi_tx_ctrl *hdmi_ctrl); static struct mdss_hw hdmi_tx_hw = { .hw_ndx = MDSS_HW_HDMI, Loading Loading @@ -1059,6 +1061,66 @@ static ssize_t hdmi_tx_sysfs_wta_avi_cn_bits(struct device *dev, return ret; } /* hdmi_tx_sysfs_wta_cn_bits */ static ssize_t hdmi_tx_sysfs_wta_s3d_mode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int rc, s3d_mode; ssize_t ret = strnlen(buf, PAGE_SIZE); struct hdmi_tx_ctrl *hdmi_ctrl = NULL; hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev); if (!hdmi_ctrl) { DEV_ERR("%s: invalid input\n", __func__); return -EINVAL; } rc = kstrtoint(buf, 10, &s3d_mode); if (rc) { DEV_ERR("%s: kstrtoint failed. rc=%d\n", __func__, rc); return rc; } if (s3d_mode < HDMI_S3D_NONE || s3d_mode >= HDMI_S3D_MAX) { DEV_ERR("%s: invalid s3d mode = %d\n", __func__, s3d_mode); return -EINVAL; } if (s3d_mode > HDMI_S3D_NONE && !hdmi_edid_is_s3d_mode_supported( hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID], hdmi_ctrl->vid_cfg.vic, s3d_mode)) { DEV_ERR("%s: s3d mode not supported in current video mode\n", __func__); return -EPERM; } hdmi_ctrl->s3d_mode = s3d_mode; hdmi_tx_set_vendor_specific_infoframe(hdmi_ctrl); DEV_DBG("%s: %d\n", __func__, hdmi_ctrl->s3d_mode); return ret; } static ssize_t hdmi_tx_sysfs_rda_s3d_mode(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t ret; struct hdmi_tx_ctrl *hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev); if (!hdmi_ctrl) { DEV_ERR("%s: invalid input\n", __func__); return -EINVAL; } ret = snprintf(buf, PAGE_SIZE, "%d\n", hdmi_ctrl->s3d_mode); DEV_DBG("%s: '%d'\n", __func__, hdmi_ctrl->s3d_mode); return ret; } static DEVICE_ATTR(connected, S_IRUGO, hdmi_tx_sysfs_rda_connected, NULL); static DEVICE_ATTR(hdmi_audio_cb, S_IWUSR, NULL, hdmi_tx_sysfs_wta_audio_cb); static DEVICE_ATTR(video_mode, S_IRUGO, hdmi_tx_sysfs_rda_video_mode, NULL); Loading @@ -1071,6 +1133,8 @@ static DEVICE_ATTR(product_description, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_wta_product_description); static DEVICE_ATTR(avi_itc, S_IWUSR, NULL, hdmi_tx_sysfs_wta_avi_itc); static DEVICE_ATTR(avi_cn0_1, S_IWUSR, NULL, hdmi_tx_sysfs_wta_avi_cn_bits); static DEVICE_ATTR(s3d_mode, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_rda_s3d_mode, hdmi_tx_sysfs_wta_s3d_mode); static struct attribute *hdmi_tx_fs_attrs[] = { &dev_attr_connected.attr, Loading @@ -1081,6 +1145,7 @@ static struct attribute *hdmi_tx_fs_attrs[] = { &dev_attr_product_description.attr, &dev_attr_avi_itc.attr, &dev_attr_avi_cn0_1.attr, &dev_attr_s3d_mode.attr, NULL, }; static struct attribute_group hdmi_tx_fs_attrs_group = { Loading Loading @@ -2075,14 +2140,13 @@ static void hdmi_tx_set_avi_infoframe(struct hdmi_tx_ctrl *hdmi_ctrl) DSS_REG_W(io, HDMI_INFOFRAME_CTRL1, reg_val); } /* hdmi_tx_set_avi_infoframe */ /* todo: add 3D support */ void hdmi_tx_set_vendor_specific_infoframe( static void hdmi_tx_set_vendor_specific_infoframe( struct hdmi_tx_ctrl *hdmi_ctrl) { int i; u8 vs_iframe[9]; /* two header + length + 6 data */ u32 sum, reg_val; u32 hdmi_vic, hdmi_video_format; u32 hdmi_vic, hdmi_video_format, s3d_struct = 0; struct dss_io_data *io = NULL; if (!hdmi_ctrl) { Loading @@ -2108,6 +2172,26 @@ void hdmi_tx_set_vendor_specific_infoframe( vs_iframe[5] = 0x0C; vs_iframe[6] = 0x00; if ((hdmi_ctrl->s3d_mode != HDMI_S3D_NONE) && hdmi_edid_is_s3d_mode_supported( hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID], hdmi_ctrl->vid_cfg.vic, hdmi_ctrl->s3d_mode)) { switch (hdmi_ctrl->s3d_mode) { case HDMI_S3D_SIDE_BY_SIDE: s3d_struct = 0x8; break; case HDMI_S3D_TOP_AND_BOTTOM: s3d_struct = 0x6; break; default: s3d_struct = 0; } hdmi_video_format = 0x2; hdmi_vic = 0; /* PB5: 3D_Structure[7:4], Reserved[3:0] */ vs_iframe[8] = s3d_struct << 4; } else { hdmi_video_format = 0x1; switch (hdmi_ctrl->vid_cfg.vic) { case HDMI_EVFRMT_3840x2160p30_16_9: Loading @@ -2126,13 +2210,12 @@ void hdmi_tx_set_vendor_specific_infoframe( hdmi_video_format = 0x0; hdmi_vic = 0x0; } /* PB5: HDMI_VIC */ vs_iframe[8] = hdmi_vic; } /* PB4: HDMI Video Format[7:5], Reserved[4:0] */ vs_iframe[7] = (hdmi_video_format << 5) & 0xE0; /* PB5: HDMI_VIC or 3D_Structure[7:4], Reserved[3:0] */ vs_iframe[8] = hdmi_vic; /* compute checksum */ sum = 0; for (i = 0; i < 9; i++) Loading @@ -2142,7 +2225,7 @@ void hdmi_tx_set_vendor_specific_infoframe( sum = 256 - sum; vs_iframe[3] = (u8)sum; reg_val = (hdmi_vic << 16) | (vs_iframe[3] << 8) | reg_val = (s3d_struct << 24) | (hdmi_vic << 16) | (vs_iframe[3] << 8) | (hdmi_video_format << 5) | vs_iframe[2]; DSS_REG_W(io, HDMI_VENSPEC_INFO0, reg_val); Loading
drivers/video/msm/mdss/mdss_hdmi_tx.h +1 −0 Original line number Diff line number Diff line Loading @@ -189,6 +189,7 @@ struct hdmi_tx_ctrl { u8 *edid_buf; u32 edid_buf_size; u32 s3d_mode; }; #endif /* __MDSS_HDMI_TX_H__ */
drivers/video/msm/mdss/mdss_hdmi_util.h +3 −3 Original line number Diff line number Diff line Loading @@ -258,9 +258,9 @@ /* SEC_CTRL version that supports HDCP SEL */ #define HDCP_SEL_MIN_SEC_VERSION (0x50010000) #define TOP_AND_BOTTOM 0x10 #define FRAME_PACKING 0x20 #define SIDE_BY_SIDE_HALF 0x40 #define TOP_AND_BOTTOM (1 << HDMI_S3D_TOP_AND_BOTTOM) #define FRAME_PACKING (1 << HDMI_S3D_FRAME_PACKING) #define SIDE_BY_SIDE_HALF (1 << HDMI_S3D_SIDE_BY_SIDE) #define LPASS_LPAIF_RDDMA_CTL0 (0xFE152000) #define LPASS_LPAIF_RDDMA_PER_CNT0 (0x00000014) Loading