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

Commit 1db73682 authored by zhaoyuan's avatar zhaoyuan
Browse files

msm: mdss: set HDMI max TMDS clock rate



Need consider both SINK and SOURCE max supported TMDS
clock. For the devices, if we set TMDS clock larger than
device caps, it could not display well. SINK max TMDS
clock could read from HDMI VSDB and HF-VSDB in EDID.

CRs-Fixed: 2035529
Change-Id: I1f31f2a05d0502367b877c4d324cbc131b2366d5
Signed-off-by: default avatarzhaoyuan <yzhao@codeaurora.org>
parent baf0fa8f
Loading
Loading
Loading
Loading
+39 −3
Original line number Diff line number Diff line
@@ -1283,6 +1283,7 @@ static void hdmi_edid_extract_speaker_allocation_data(
static void hdmi_edid_extract_sink_caps(struct hdmi_edid_ctrl *edid_ctrl,
	const u8 *in_buf)
{
	u8 len;
	const u8 *vsd = NULL;

	if (!edid_ctrl) {
@@ -1297,11 +1298,27 @@ static void hdmi_edid_extract_sink_caps(struct hdmi_edid_ctrl *edid_ctrl,
		edid_ctrl->basic_audio_supp = false;
	pr_debug("%s: basic audio supported: %s\n", __func__,
		edid_ctrl->basic_audio_supp ? "true" : "false");
	vsd = hdmi_edid_find_block(in_buf, DBC_START_OFFSET,
		VENDOR_SPECIFIC_DATA_BLOCK, &len);

	if (vsd == NULL || len == 0 || len > MAX_DATA_BLOCK_SIZE)
		return;

	/* Max TMDS clock is in  multiples of 5Mhz. */
	edid_ctrl->sink_caps.max_pclk_in_hz = vsd[7] * 5000000;

	vsd = hdmi_edid_find_hfvsdb(in_buf);

	if (vsd) {
		/* Max pixel clock is in  multiples of 5Mhz. */
		/*
		 * HF-VSDB define larger TMDS clock than VSDB. If sink
		 * supports TMDS Character Rates > 340M, the sink shall
		 * set Max_TMDS_Character_Rates appropriately and non-zero.
		 * Or, if sink dose not support TMDS Character Rates > 340M,
		 * the sink shall set this filed to 0. The max TMDS support
		 * clock Rate = Max_TMDS_Character_Rates * 5Mhz.
		 */
		if (vsd[5] != 0)
			edid_ctrl->sink_caps.max_pclk_in_hz =
					vsd[5] * 5000000;
		edid_ctrl->sink_caps.scdc_present =
@@ -2424,6 +2441,25 @@ bool hdmi_edid_is_dvi_mode(void *input)
		return true;
}

/**
 * hdmi_edid_get_sink_caps_max_tmds_clk() - get max tmds clock supported.
 * Sink side's limitation should be concerned as well.
 * @input: edid parser data
 *
 * Return: max tmds clock
 */
u32 hdmi_edid_get_sink_caps_max_tmds_clk(void *input)
{
	struct hdmi_edid_ctrl *edid_ctrl = (struct hdmi_edid_ctrl *)input;

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

	return edid_ctrl->sink_caps.max_pclk_in_hz;
}

/**
 * hdmi_edid_get_deep_color() - get deep color info supported by sink
 * @input: edid parser data
+1 −0
Original line number Diff line number Diff line
@@ -81,5 +81,6 @@ void hdmi_edid_config_override(void *input, bool enable,
		struct hdmi_edid_override_data *data);
void hdmi_edid_set_max_pclk_rate(void *input, u32 max_pclk_khz);
bool hdmi_edid_is_audio_supported(void *input);
u32 hdmi_edid_get_sink_caps_max_tmds_clk(void *input);

#endif /* __HDMI_EDID_H__ */
+8 −0
Original line number Diff line number Diff line
@@ -2224,6 +2224,14 @@ static int hdmi_tx_read_sink_info(struct hdmi_tx_ctrl *hdmi_ctrl)
		status = hdmi_edid_parser(data);
		if (status)
			DEV_ERR("%s: edid parse failed\n", __func__);
		else
			/*
			 * Updata HDMI max supported TMDS clock, consider
			 * both sink and source capicity.
			 */
			hdmi_edid_set_max_pclk_rate(data,
			  min(hdmi_edid_get_sink_caps_max_tmds_clk(data) / 1000,
			      hdmi_ctrl->max_pclk_khz));
	}
bail:
	if (hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_DDC_PM, false))