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

Commit 76f80210 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: add support to dynamically add new resolutions"

parents 6473a272 50cf1983
Loading
Loading
Loading
Loading
+74 −1
Original line number Original line Diff line number Diff line
@@ -132,6 +132,7 @@ struct hdmi_edid_ctrl {
	int sadb_size;
	int sadb_size;
	u8 edid_buf[MAX_EDID_SIZE];
	u8 edid_buf[MAX_EDID_SIZE];
	char vendor_id[EDID_VENDOR_ID_SIZE];
	char vendor_id[EDID_VENDOR_ID_SIZE];
	bool keep_resv_timings;


	struct hdmi_edid_sink_data sink_data;
	struct hdmi_edid_sink_data sink_data;
	struct hdmi_edid_init_data init_data;
	struct hdmi_edid_init_data init_data;
@@ -176,6 +177,7 @@ static int hdmi_edid_reset_parser(struct hdmi_edid_ctrl *edid_ctrl)
	edid_ctrl->sadb_size = 0;
	edid_ctrl->sadb_size = 0;


	/* reset new resolution details */
	/* reset new resolution details */
	if (!edid_ctrl->keep_resv_timings)
		hdmi_reset_resv_timing_info();
		hdmi_reset_resv_timing_info();


	return 0;
	return 0;
@@ -573,6 +575,60 @@ static ssize_t hdmi_common_rda_edid_raw_data(struct device *dev,
} /* hdmi_common_rda_edid_raw_data */
} /* hdmi_common_rda_edid_raw_data */
static DEVICE_ATTR(edid_raw_data, S_IRUGO, hdmi_common_rda_edid_raw_data, NULL);
static DEVICE_ATTR(edid_raw_data, S_IRUGO, hdmi_common_rda_edid_raw_data, NULL);


static ssize_t hdmi_edid_sysfs_wta_add_resolution(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
	int rc;
	ssize_t ret = strnlen(buf, PAGE_SIZE);
	struct hdmi_edid_ctrl *edid_ctrl = hdmi_edid_get_ctrl(dev);
	struct msm_hdmi_mode_timing_info timing;

	if (!edid_ctrl) {
		DEV_ERR("%s: invalid input\n", __func__);
		return -EINVAL;
	}

	rc = sscanf(buf,
		"%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
		(unsigned long *) &timing.active_h,
		(unsigned long *) &timing.front_porch_h,
		(unsigned long *) &timing.pulse_width_h,
		(unsigned long *) &timing.back_porch_h,
		(unsigned long *) &timing.active_low_h,
		(unsigned long *) &timing.active_v,
		(unsigned long *) &timing.front_porch_v,
		(unsigned long *) &timing.pulse_width_v,
		(unsigned long *) &timing.back_porch_v,
		(unsigned long *) &timing.active_low_v,
		(unsigned long *) &timing.pixel_freq,
		(unsigned long *) &timing.refresh_rate,
		(unsigned long *) &timing.interlaced,
		(unsigned long *) &timing.supported,
		(unsigned long *) &timing.ar);

	if (rc != 15) {
		DEV_ERR("%s: error reading buf\n", __func__);
		goto err;
	}

	rc = hdmi_set_resv_timing_info(&timing);

	if (!IS_ERR_VALUE(rc)) {
		DEV_DBG("%s: added new res %d\n", __func__, rc);
	} else {
		DEV_ERR("%s: error adding new res %d\n", __func__, rc);
		goto err;
	}

	edid_ctrl->keep_resv_timings = true;
	return ret;

err:
	edid_ctrl->keep_resv_timings = false;
	return -EFAULT;
}
static DEVICE_ATTR(add_res, S_IWUSR, NULL, hdmi_edid_sysfs_wta_add_resolution);

static struct attribute *hdmi_edid_fs_attrs[] = {
static struct attribute *hdmi_edid_fs_attrs[] = {
	&dev_attr_edid_modes.attr,
	&dev_attr_edid_modes.attr,
	&dev_attr_pa.attr,
	&dev_attr_pa.attr,
@@ -584,6 +640,7 @@ static struct attribute *hdmi_edid_fs_attrs[] = {
	&dev_attr_edid_audio_latency.attr,
	&dev_attr_edid_audio_latency.attr,
	&dev_attr_edid_video_latency.attr,
	&dev_attr_edid_video_latency.attr,
	&dev_attr_res_info.attr,
	&dev_attr_res_info.attr,
	&dev_attr_add_res.attr,
	NULL,
	NULL,
};
};


@@ -1942,6 +1999,19 @@ end:
	return ret;
	return ret;
}
}


static void hdmi_edid_add_resv_timings(struct hdmi_edid_ctrl *edid_ctrl)
{
	int i = HDMI_VFRMT_RESERVE1;

	while (i <= RESERVE_VFRMT_END) {
		if (hdmi_is_valid_resv_timing(i))
			hdmi_edid_add_sink_video_format(edid_ctrl, i);
		else
			break;
		i++;
	}
}

int hdmi_edid_parser(void *input)
int hdmi_edid_parser(void *input)
{
{
	u8 *edid_buf = NULL;
	u8 *edid_buf = NULL;
@@ -2022,6 +2092,9 @@ bail:


	hdmi_edid_get_display_mode(edid_ctrl);
	hdmi_edid_get_display_mode(edid_ctrl);


	if (edid_ctrl->keep_resv_timings)
		hdmi_edid_add_resv_timings(edid_ctrl);

	return 0;
	return 0;


err_invalid_header:
err_invalid_header:
+15 −0
Original line number Original line Diff line number Diff line
@@ -114,6 +114,21 @@ int hdmi_set_resv_timing_info(struct msm_hdmi_mode_timing_info *mode)
	return -ENOMEM;
	return -ENOMEM;
}
}


bool hdmi_is_valid_resv_timing(int mode)
{
	struct msm_hdmi_mode_timing_info *info;

	if (mode < HDMI_VFRMT_RESERVE1 || mode > RESERVE_VFRMT_END) {
		DEV_ERR("%s: invalid mode %d\n", __func__, mode);
		return false;
	}

	info = &hdmi_resv_timings[mode - HDMI_VFRMT_RESERVE1];

	return info->video_format >= HDMI_VFRMT_RESERVE1 &&
		info->video_format <= RESERVE_VFRMT_END;
}

void hdmi_reset_resv_timing_info(void)
void hdmi_reset_resv_timing_info(void)
{
{
	int i;
	int i;
+1 −0
Original line number Original line Diff line number Diff line
@@ -459,6 +459,7 @@ int hdmi_get_supported_mode(struct msm_hdmi_mode_timing_info *info,
ssize_t hdmi_get_video_3d_fmt_2string(u32 format, char *buf, u32 size);
ssize_t hdmi_get_video_3d_fmt_2string(u32 format, char *buf, u32 size);
const char *msm_hdmi_mode_2string(u32 mode);
const char *msm_hdmi_mode_2string(u32 mode);
int hdmi_set_resv_timing_info(struct msm_hdmi_mode_timing_info *mode);
int hdmi_set_resv_timing_info(struct msm_hdmi_mode_timing_info *mode);
bool hdmi_is_valid_resv_timing(int mode);
void hdmi_reset_resv_timing_info(void);
void hdmi_reset_resv_timing_info(void);


/* todo: Fix this. Right now this is defined in mdss_hdmi_tx.c */
/* todo: Fix this. Right now this is defined in mdss_hdmi_tx.c */