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

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

Merge "drm/msm: Clear HDMI VSDB and VCDB info across hotplug"

parents 40286db8 74fe6935
Loading
Loading
Loading
Loading
+61 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
 * Copyright (C) 2013 Red Hat
 * Author: Rob Clark <robdclark@gmail.com>
 *
@@ -124,6 +124,55 @@ static void sde_hdmi_clear_hdr_info(struct drm_bridge *bridge)
	connector->hdr_supported = false;
}

static void sde_hdmi_clear_vsdb_info(struct drm_bridge *bridge)
{
	struct sde_hdmi_bridge *sde_hdmi_bridge = to_hdmi_bridge(bridge);
	struct hdmi *hdmi = sde_hdmi_bridge->hdmi;
	struct drm_connector *connector = hdmi->connector;

	connector->max_tmds_clock = 0;
	connector->latency_present[0] = false;
	connector->latency_present[1] = false;
	connector->video_latency[0] = false;
	connector->video_latency[1] = false;
	connector->audio_latency[0] = false;
	connector->audio_latency[1] = false;
}

static void sde_hdmi_clear_hf_vsdb_info(struct drm_bridge *bridge)
{
	struct sde_hdmi_bridge *sde_hdmi_bridge = to_hdmi_bridge(bridge);
	struct hdmi *hdmi = sde_hdmi_bridge->hdmi;
	struct drm_connector *connector = hdmi->connector;

	connector->max_tmds_char = 0;
	connector->scdc_present = false;
	connector->rr_capable = false;
	connector->supports_scramble = false;
	connector->flags_3d = 0;
}

static void sde_hdmi_clear_vcdb_info(struct drm_bridge *bridge)
{
	struct sde_hdmi_bridge *sde_hdmi_bridge = to_hdmi_bridge(bridge);
	struct hdmi *hdmi = sde_hdmi_bridge->hdmi;
	struct drm_connector *connector = hdmi->connector;

	connector->pt_scan_info = 0;
	connector->it_scan_info = 0;
	connector->ce_scan_info = 0;
	connector->rgb_qs = false;
	connector->yuv_qs = false;
}

static void sde_hdmi_clear_vsdbs(struct drm_bridge *bridge)
{
	/* Clear fields of HDMI VSDB */
	sde_hdmi_clear_vsdb_info(bridge);
	/* Clear fields of HDMI forum VSDB */
	sde_hdmi_clear_hf_vsdb_info(bridge);
}

static void _sde_hdmi_bridge_power_on(struct drm_bridge *bridge)
{
	struct sde_hdmi_bridge *sde_hdmi_bridge = to_hdmi_bridge(bridge);
@@ -574,6 +623,12 @@ static void _sde_hdmi_bridge_disable(struct drm_bridge *bridge)

	mutex_lock(&display->display_lock);

	if (!bridge) {
		SDE_ERROR("Invalid params\n");
		mutex_unlock(&display->display_lock);
		return;
	}

	display->pll_update_enable = false;
	display->sink_hdcp_ver = SDE_HDMI_HDCP_NONE;
	display->sink_hdcp22_support = false;
@@ -582,6 +637,11 @@ static void _sde_hdmi_bridge_disable(struct drm_bridge *bridge)
		sde_hdmi_hdcp_off(display);

	sde_hdmi_clear_hdr_info(bridge);
	/* Clear HDMI VSDB blocks info */
	sde_hdmi_clear_vsdbs(bridge);
	/* Clear HDMI VCDB block info */
	sde_hdmi_clear_vcdb_info(bridge);

	mutex_unlock(&display->display_lock);
}

+24 −18
Original line number Diff line number Diff line
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -252,12 +252,13 @@ static void sde_edid_parse_Y420CMDB(
struct drm_connector *connector, struct sde_edid_ctrl *edid_ctrl,
const u8 *db)
{
	u32 offset = 0;
	u8 cmdb_len = 0;
	u8 svd_len = 0;
	const u8 *svd = NULL;
	u32 i = 0, j = 0;
	u32 i = 0;
	u32 video_format = 0;
	u32 num_cmdb_svd = 0;
	const u32 mult = 8;

	if (!edid_ctrl) {
		DEV_ERR("%s: edid_ctrl is NULL\n", __func__);
@@ -271,8 +272,8 @@ const u8 *db)
	SDE_EDID_DEBUG("%s +\n", __func__);
	cmdb_len = db[0] & 0x1f;

	/* Byte 3 to L+1 contain SVDs */
	offset += 2;
	if (cmdb_len < 1)
		return;

	svd = sde_edid_find_block(edid_ctrl->edid, VIDEO_DATA_BLOCK);

@@ -282,21 +283,26 @@ const u8 *db)
		++svd;
	}

	for (i = 0; i < svd_len; i++, j++) {
	if (cmdb_len == 1)
		num_cmdb_svd = svd_len;
	else {
		num_cmdb_svd = (cmdb_len - 1) * mult;
		if (num_cmdb_svd > svd_len)
			num_cmdb_svd = svd_len;
	}

	for (i = 0; i < num_cmdb_svd; i++) {
		video_format = *(svd + i) & 0x7F;
		if (cmdb_len == 1) {
			/* If cmdb_len is 1, it means all SVDs support YUV */
			sde_edid_set_y420_support(connector, video_format);
		} else if (db[offset] & (1 << j)) {
		/*
		 * If cmdb_len is 1, it means all SVDs support YUV
		 * Else, we check each byte of the cmdb bitmap bitwise
		 * and match those bits with the formats populated
		 * during the parsing of the Video Data Blocks.
		 * Refer to CTA 861-F section 7.5.11 YCBCR 4:2:0 Capability
		 * Map Data Block for more details on this.
		 */
		if (cmdb_len == 1 || (db[2 + i / mult] & (1 << (i % mult))))
			sde_edid_set_y420_support(connector, video_format);

			if (j & 0x80) {
				j = j/8;
				offset++;
				if (offset >= cmdb_len)
					break;
			}
		}
	}

	SDE_EDID_DEBUG("%s -\n", __func__);