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

Commit 377bd8a9 authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/radeon: use a fetch function to get the edid

We keep a cached version of the edid in radeon_connector which
we use for determining connectedness and when to enable certain
features like hdmi audio, etc.  When the user uses the firmware
interface to override the driver with some other edid the driver's
copy is never updated.  The fetch function will check if there
is a user supplied edid and update the driver's copy if there
is.

bug:
https://bugs.freedesktop.org/show_bug.cgi?id=80691



Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 72a5c970
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -716,7 +716,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
			if (radeon_connector->use_digital &&
			    (radeon_connector->audio == RADEON_AUDIO_ENABLE))
				return ATOM_ENCODER_MODE_HDMI;
			else if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
			else if (drm_detect_hdmi_monitor(radeon_connector_edid(connector)) &&
				 (radeon_connector->audio == RADEON_AUDIO_AUTO))
				return ATOM_ENCODER_MODE_HDMI;
			else if (radeon_connector->use_digital)
@@ -735,7 +735,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
		if (radeon_audio != 0) {
			if (radeon_connector->audio == RADEON_AUDIO_ENABLE)
				return ATOM_ENCODER_MODE_HDMI;
			else if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
			else if (drm_detect_hdmi_monitor(radeon_connector_edid(connector)) &&
				 (radeon_connector->audio == RADEON_AUDIO_AUTO))
				return ATOM_ENCODER_MODE_HDMI;
			else
@@ -755,7 +755,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
		} else if (radeon_audio != 0) {
			if (radeon_connector->audio == RADEON_AUDIO_ENABLE)
				return ATOM_ENCODER_MODE_HDMI;
			else if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
			else if (drm_detect_hdmi_monitor(radeon_connector_edid(connector)) &&
				 (radeon_connector->audio == RADEON_AUDIO_AUTO))
				return ATOM_ENCODER_MODE_HDMI;
			else
+2 −2
Original line number Diff line number Diff line
@@ -175,7 +175,7 @@ void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder)
		return;
	}

	sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb);
	sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb);
	if (sad_count <= 0) {
		DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
		return;
@@ -238,7 +238,7 @@ void dce6_afmt_write_sad_regs(struct drm_encoder *encoder)
		return;
	}

	sad_count = drm_edid_to_sad(radeon_connector->edid, &sads);
	sad_count = drm_edid_to_sad(radeon_connector_edid(connector), &sads);
	if (sad_count <= 0) {
		DRM_ERROR("Couldn't read SADs: %d\n", sad_count);
		return;
+2 −2
Original line number Diff line number Diff line
@@ -117,7 +117,7 @@ static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder)
		return;
	}

	sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb);
	sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb);
	if (sad_count <= 0) {
		DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
		return;
@@ -172,7 +172,7 @@ static void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder)
		return;
	}

	sad_count = drm_edid_to_sad(radeon_connector->edid, &sads);
	sad_count = drm_edid_to_sad(radeon_connector_edid(connector), &sads);
	if (sad_count <= 0) {
		DRM_ERROR("Couldn't read SADs: %d\n", sad_count);
		return;
+21 −6
Original line number Diff line number Diff line
@@ -107,7 +107,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector)
	case DRM_MODE_CONNECTOR_DVII:
	case DRM_MODE_CONNECTOR_HDMIB:
		if (radeon_connector->use_digital) {
			if (drm_detect_hdmi_monitor(radeon_connector->edid)) {
			if (drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
				if (connector->display_info.bpc)
					bpc = connector->display_info.bpc;
			}
@@ -115,7 +115,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector)
		break;
	case DRM_MODE_CONNECTOR_DVID:
	case DRM_MODE_CONNECTOR_HDMIA:
		if (drm_detect_hdmi_monitor(radeon_connector->edid)) {
		if (drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
			if (connector->display_info.bpc)
				bpc = connector->display_info.bpc;
		}
@@ -124,7 +124,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector)
		dig_connector = radeon_connector->con_priv;
		if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
		    (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) ||
		    drm_detect_hdmi_monitor(radeon_connector->edid)) {
		    drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
			if (connector->display_info.bpc)
				bpc = connector->display_info.bpc;
		}
@@ -148,7 +148,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector)
		break;
	}

	if (drm_detect_hdmi_monitor(radeon_connector->edid)) {
	if (drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
		/* hdmi deep color only implemented on DCE4+ */
		if ((bpc > 8) && !ASIC_IS_DCE4(rdev)) {
			DRM_DEBUG("%s: HDMI deep color %d bpc unsupported. Using 8 bpc.\n",
@@ -262,6 +262,21 @@ static struct drm_encoder *radeon_find_encoder(struct drm_connector *connector,
	return NULL;
}

struct edid *radeon_connector_edid(struct drm_connector *connector)
{
	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
	struct drm_property_blob *edid_blob = connector->edid_blob_ptr;

	if (radeon_connector->edid) {
		return radeon_connector->edid;
	} else if (edid_blob) {
		struct edid *edid = kmemdup(edid_blob->data, edid_blob->length, GFP_KERNEL);
		if (edid)
			radeon_connector->edid = edid;
	}
	return radeon_connector->edid;
}

static void radeon_connector_get_edid(struct drm_connector *connector)
{
	struct drm_device *dev = connector->dev;
@@ -1366,7 +1381,7 @@ static int radeon_dvi_mode_valid(struct drm_connector *connector,
		    (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) ||
		    (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B))
			return MODE_OK;
		else if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) {
		else if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
			/* HDMI 1.3+ supports max clock of 340 Mhz */
			if (mode->clock > 340000)
				return MODE_CLOCK_HIGH;
@@ -1660,7 +1675,7 @@ static int radeon_dp_mode_valid(struct drm_connector *connector,
		    (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {
			return radeon_dp_mode_valid_helper(connector, mode);
		} else {
			if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) {
			if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
				/* HDMI 1.3+ supports max clock of 340 Mhz */
				if (mode->clock > 340000)
					return MODE_CLOCK_HIGH;
+1 −1
Original line number Diff line number Diff line
@@ -1691,7 +1691,7 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
			    (!(mode->flags & DRM_MODE_FLAG_INTERLACE)) &&
			    ((radeon_encoder->underscan_type == UNDERSCAN_ON) ||
			     ((radeon_encoder->underscan_type == UNDERSCAN_AUTO) &&
			      drm_detect_hdmi_monitor(radeon_connector->edid) &&
			      drm_detect_hdmi_monitor(radeon_connector_edid(connector)) &&
			      is_hdtv_mode(mode)))) {
				if (radeon_encoder->underscan_hborder != 0)
					radeon_crtc->h_border = radeon_encoder->underscan_hborder;
Loading