Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ef06c660 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: mdss: hdmi: s3d mode support"

parents a7ab05bb 89f07229
Loading
Loading
Loading
Loading
+28 −5
Original line number Diff line number Diff line
@@ -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;
};
@@ -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));
@@ -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);
@@ -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;
+2 −0
Original line number Diff line number Diff line
@@ -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__ */
+109 −26
Original line number Diff line number Diff line
@@ -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,
@@ -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);
@@ -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,
@@ -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 = {
@@ -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) {
@@ -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:
@@ -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++)
@@ -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);

+1 −0
Original line number Diff line number Diff line
@@ -189,6 +189,7 @@ struct hdmi_tx_ctrl {

	u8 *edid_buf;
	u32 edid_buf_size;
	u32 s3d_mode;
};

#endif /* __MDSS_HDMI_TX_H__ */
+3 −3
Original line number Diff line number Diff line
@@ -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)