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

Commit a03fd469 authored by Ajay Singh Parmar's avatar Ajay Singh Parmar
Browse files

msm: mdss: edid: parse dtd and proper fps and pclk check



Parse the Detailed Timing Descriptors of both EDID blocks for
resolutions. Check if the resolution is already added in local
data base. Also, add tolerance to fps and pclk variations for
a give resolution so that EDID parser can capture all the
resolutions correctly as published by the sink's EDID.

Change-Id: I113988eb21f82eef022723c421b1c1c9d4dead9f
Signed-off-by: default avatarAjay Singh Parmar <aparmar@codeaurora.org>
parent 057bdafd
Loading
Loading
Loading
Loading
+75 −95
Original line number Diff line number Diff line
@@ -698,7 +698,6 @@ static ssize_t hdmi_edid_sysfs_rda_3d_modes(struct device *dev,
		}
	}

	DEV_DBG("%s: '%s'\n", __func__, buf);
	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "\n");

	return ret;
@@ -1567,7 +1566,9 @@ static void hdmi_edid_detail_desc(struct hdmi_edid_ctrl *edid_ctrl,
	frame_data = (active_h + blank_h) * (active_v + blank_v);

	if (frame_data) {
		int refresh_rate_khz = (pixel_clk * khz_to_hz) / frame_data;
		u64 refresh_rate = (u64)pixel_clk * khz_to_hz * khz_to_hz;

		do_div(refresh_rate, frame_data);

		timing.active_h      = active_h;
		timing.front_porch_h = front_porch_h;
@@ -1582,18 +1583,23 @@ static void hdmi_edid_detail_desc(struct hdmi_edid_ctrl *edid_ctrl,
					(front_porch_v + pulse_width_v);
		timing.active_low_v  = active_low_v;
		timing.pixel_freq    = pixel_clk;
		timing.refresh_rate  = refresh_rate_khz * khz_to_hz;
		timing.refresh_rate  = refresh_rate;
		timing.interlaced    = interlaced;
		timing.supported     = true;
		timing.ar            = aspect_ratio_4_3 ? HDMI_RES_AR_4_3 :
					(aspect_ratio_5_4 ? HDMI_RES_AR_5_4 :
					HDMI_RES_AR_16_9);

		DEV_DBG("%s: new res: %dx%d%s@%dHz\n", __func__,
		DEV_DBG("%s: new res: %dx%d%s@%d.%d%d%dHz\n", __func__,
			timing.active_h, timing.active_v,
			interlaced ? "i" : "p",
			timing.refresh_rate / khz_to_hz);
			timing.refresh_rate / khz_to_hz,
			(timing.refresh_rate % khz_to_hz) / 100,
			(timing.refresh_rate % 100) / 10,
			timing.refresh_rate % 10);

		rc = hdmi_get_video_id_code(&timing, NULL);
		if (rc < 0)
			rc = hdmi_set_resv_timing_info(&timing);
	} else {
		DEV_ERR("%s: Invalid frame data\n", __func__);
@@ -1642,6 +1648,7 @@ static void hdmi_edid_add_sink_video_format(struct hdmi_edid_ctrl *edid_ctrl,
	u32 supported = hdmi_edid_is_mode_supported(edid_ctrl, &timing);
	struct hdmi_edid_sink_data *sink_data = &edid_ctrl->sink_data;
	struct disp_mode_info *disp_mode_list = sink_data->disp_mode_list;
	u32 i = 0;

	if (video_format >= HDMI_VFRMT_MAX) {
		DEV_ERR("%s: video format: %s is not supported\n", __func__,
@@ -1653,6 +1660,15 @@ static void hdmi_edid_add_sink_video_format(struct hdmi_edid_ctrl *edid_ctrl,
		video_format, msm_hdmi_mode_2string(video_format),
		supported ? "Supported" : "Not-Supported");

	for (i = 0; i < sink_data->num_of_elements; i++) {
		u32 vic = disp_mode_list[i].video_format;

		if (vic == video_format) {
			DEV_DBG("%s: vic %d already added\n", __func__, vic);
			return;
		}
	}

	if (!ret && supported) {
		/* todo: MHL */
		disp_mode_list[sink_data->num_of_elements].video_format =
@@ -1970,6 +1986,7 @@ static void hdmi_edid_get_display_mode(struct hdmi_edid_ctrl *edid_ctrl)
	const u8 *svd = NULL;
	u32 has60hz_mode = false;
	u32 has50hz_mode = false;
	u32 desc_offset = 0;
	bool read_block0_res = false;
	struct hdmi_edid_sink_data *sink_data = NULL;

@@ -2033,47 +2050,10 @@ static void hdmi_edid_get_display_mode(struct hdmi_edid_ctrl *edid_ctrl)
			if (video_format == HDMI_VFRMT_640x480p60_4_3)
				has480p = true;
		}
	} else if (!num_of_cea_blocks || read_block0_res) {
		/* Detailed timing descriptors */
		u32 desc_offset = 0;
		/*
		 * * Maximum 4 timing descriptor in block 0 - No CEA
		 *   extension in this case
		 * * EDID_FIRST_TIMING_DESC[0x36] - 1st detailed timing
		 *   descriptor
		 * * EDID_DETAIL_TIMING_DESC_BLCK_SZ[0x12] - Each detailed
		 *   timing descriptor has block size of 18
		 */
		while (4 > i && 0 != edid_blk0[0x36+desc_offset]) {
			hdmi_edid_detail_desc(edid_ctrl,
				edid_blk0+0x36+desc_offset,
				&video_format);

			DEV_DBG("[%s:%d] Block-0 Adding vid fmt = [%s]\n",
				__func__, __LINE__,
				msm_hdmi_mode_2string(video_format));

			hdmi_edid_add_sink_video_format(edid_ctrl,
				video_format);

			if (video_format == HDMI_VFRMT_640x480p60_4_3)
				has480p = true;

			/* Make a note of the preferred video format */
			if (i == 0) {
				sink_data->preferred_video_format =
					video_format;
			}
			desc_offset += 0x12;
			++i;
	}
	} else if (1 == num_of_cea_blocks) {
		u32 desc_offset = 0;

		/*
		 * Read from both block 0 and block 1
		 * Read EDID block[0] as above
		 */
	i = 0;
	/* Read DTD resolutions from block0 */
	while (4 > i && 0 != edid_blk0[0x36+desc_offset]) {
		hdmi_edid_detail_desc(edid_ctrl,
			edid_blk0+0x36+desc_offset,
@@ -2108,7 +2088,8 @@ static void hdmi_edid_get_display_mode(struct hdmi_edid_ctrl *edid_ctrl)
	 * * EDID_BLOCK_SIZE = 0x80  Each page size in the EDID ROM
	 */
	desc_offset = edid_blk1[0x02];
		while (0 != edid_blk1[desc_offset]) {
	i = 0;
	while (!edid_blk1[desc_offset]) {
		hdmi_edid_detail_desc(edid_ctrl,
			edid_blk1+desc_offset,
			&video_format);
@@ -2130,7 +2111,6 @@ static void hdmi_edid_get_display_mode(struct hdmi_edid_ctrl *edid_ctrl)
		desc_offset += 0x12;
		++i;
	}
	}

	std_blk = 0;
	offset  = 0;
+13 −4
Original line number Diff line number Diff line
@@ -625,7 +625,7 @@ int hdmi_get_video_id_code(struct msm_hdmi_mode_timing_info *timing_in,
{
	int i, vic = -1;
	struct msm_hdmi_mode_timing_info supported_timing = {0};
	u32 ret;
	u32 ret, pclk_delta, pclk, fps_delta, fps;

	if (!timing_in) {
		pr_err("invalid input\n");
@@ -633,9 +633,16 @@ int hdmi_get_video_id_code(struct msm_hdmi_mode_timing_info *timing_in,
	}

	/* active_low_h, active_low_v and interlaced are not checked against */
	for (i = 0; i < HDMI_VFRMT_MAX; i++) {
	for (i = 1; i < HDMI_VFRMT_MAX; i++) {
		ret = hdmi_get_supported_mode(&supported_timing, ds_data, i);

		pclk = supported_timing.pixel_freq;
		fps = supported_timing.refresh_rate;

		/* as per standard, 0.5% of deviation is allowed */
		pclk_delta = (pclk / HDMI_KHZ_TO_HZ) * 5;
		fps_delta = (fps / HDMI_KHZ_TO_HZ) * 5;

		if (ret || !supported_timing.supported)
			continue;
		if (timing_in->active_h != supported_timing.active_h)
@@ -654,9 +661,11 @@ int hdmi_get_video_id_code(struct msm_hdmi_mode_timing_info *timing_in,
			continue;
		if (timing_in->back_porch_v != supported_timing.back_porch_v)
			continue;
		if (timing_in->pixel_freq != supported_timing.pixel_freq)
		if (timing_in->pixel_freq < (pclk - pclk_delta) ||
		    timing_in->pixel_freq > (pclk + pclk_delta))
			continue;
		if (timing_in->refresh_rate != supported_timing.refresh_rate)
		if (timing_in->refresh_rate < (fps - fps_delta) ||
		    timing_in->refresh_rate > (fps + fps_delta))
			continue;

		vic = (int)supported_timing.video_format;