Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Alex Deucher <alexander.deucher@amd.com>

+33 -16
+3 -3
drivers/gpu/drm/radeon/atombios_encoders.c
··· 716 716 if (radeon_connector->use_digital && 717 717 (radeon_connector->audio == RADEON_AUDIO_ENABLE)) 718 718 return ATOM_ENCODER_MODE_HDMI; 719 - else if (drm_detect_hdmi_monitor(radeon_connector->edid) && 719 + else if (drm_detect_hdmi_monitor(radeon_connector_edid(connector)) && 720 720 (radeon_connector->audio == RADEON_AUDIO_AUTO)) 721 721 return ATOM_ENCODER_MODE_HDMI; 722 722 else if (radeon_connector->use_digital) ··· 735 735 if (radeon_audio != 0) { 736 736 if (radeon_connector->audio == RADEON_AUDIO_ENABLE) 737 737 return ATOM_ENCODER_MODE_HDMI; 738 - else if (drm_detect_hdmi_monitor(radeon_connector->edid) && 738 + else if (drm_detect_hdmi_monitor(radeon_connector_edid(connector)) && 739 739 (radeon_connector->audio == RADEON_AUDIO_AUTO)) 740 740 return ATOM_ENCODER_MODE_HDMI; 741 741 else ··· 755 755 } else if (radeon_audio != 0) { 756 756 if (radeon_connector->audio == RADEON_AUDIO_ENABLE) 757 757 return ATOM_ENCODER_MODE_HDMI; 758 - else if (drm_detect_hdmi_monitor(radeon_connector->edid) && 758 + else if (drm_detect_hdmi_monitor(radeon_connector_edid(connector)) && 759 759 (radeon_connector->audio == RADEON_AUDIO_AUTO)) 760 760 return ATOM_ENCODER_MODE_HDMI; 761 761 else
+2 -2
drivers/gpu/drm/radeon/dce6_afmt.c
··· 175 175 return; 176 176 } 177 177 178 - sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb); 178 + sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb); 179 179 if (sad_count <= 0) { 180 180 DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); 181 181 return; ··· 238 238 return; 239 239 } 240 240 241 - sad_count = drm_edid_to_sad(radeon_connector->edid, &sads); 241 + sad_count = drm_edid_to_sad(radeon_connector_edid(connector), &sads); 242 242 if (sad_count <= 0) { 243 243 DRM_ERROR("Couldn't read SADs: %d\n", sad_count); 244 244 return;
+2 -2
drivers/gpu/drm/radeon/evergreen_hdmi.c
··· 117 117 return; 118 118 } 119 119 120 - sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb); 120 + sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb); 121 121 if (sad_count <= 0) { 122 122 DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); 123 123 return; ··· 172 172 return; 173 173 } 174 174 175 - sad_count = drm_edid_to_sad(radeon_connector->edid, &sads); 175 + sad_count = drm_edid_to_sad(radeon_connector_edid(connector), &sads); 176 176 if (sad_count <= 0) { 177 177 DRM_ERROR("Couldn't read SADs: %d\n", sad_count); 178 178 return;
+21 -6
drivers/gpu/drm/radeon/radeon_connectors.c
··· 107 107 case DRM_MODE_CONNECTOR_DVII: 108 108 case DRM_MODE_CONNECTOR_HDMIB: 109 109 if (radeon_connector->use_digital) { 110 - if (drm_detect_hdmi_monitor(radeon_connector->edid)) { 110 + if (drm_detect_hdmi_monitor(radeon_connector_edid(connector))) { 111 111 if (connector->display_info.bpc) 112 112 bpc = connector->display_info.bpc; 113 113 } ··· 115 115 break; 116 116 case DRM_MODE_CONNECTOR_DVID: 117 117 case DRM_MODE_CONNECTOR_HDMIA: 118 - if (drm_detect_hdmi_monitor(radeon_connector->edid)) { 118 + if (drm_detect_hdmi_monitor(radeon_connector_edid(connector))) { 119 119 if (connector->display_info.bpc) 120 120 bpc = connector->display_info.bpc; 121 121 } ··· 124 124 dig_connector = radeon_connector->con_priv; 125 125 if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || 126 126 (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) || 127 - drm_detect_hdmi_monitor(radeon_connector->edid)) { 127 + drm_detect_hdmi_monitor(radeon_connector_edid(connector))) { 128 128 if (connector->display_info.bpc) 129 129 bpc = connector->display_info.bpc; 130 130 } ··· 148 148 break; 149 149 } 150 150 151 - if (drm_detect_hdmi_monitor(radeon_connector->edid)) { 151 + if (drm_detect_hdmi_monitor(radeon_connector_edid(connector))) { 152 152 /* hdmi deep color only implemented on DCE4+ */ 153 153 if ((bpc > 8) && !ASIC_IS_DCE4(rdev)) { 154 154 DRM_DEBUG("%s: HDMI deep color %d bpc unsupported. Using 8 bpc.\n", ··· 260 260 return encoder; 261 261 } 262 262 return NULL; 263 + } 264 + 265 + struct edid *radeon_connector_edid(struct drm_connector *connector) 266 + { 267 + struct radeon_connector *radeon_connector = to_radeon_connector(connector); 268 + struct drm_property_blob *edid_blob = connector->edid_blob_ptr; 269 + 270 + if (radeon_connector->edid) { 271 + return radeon_connector->edid; 272 + } else if (edid_blob) { 273 + struct edid *edid = kmemdup(edid_blob->data, edid_blob->length, GFP_KERNEL); 274 + if (edid) 275 + radeon_connector->edid = edid; 276 + } 277 + return radeon_connector->edid; 263 278 } 264 279 265 280 static void radeon_connector_get_edid(struct drm_connector *connector) ··· 1381 1366 (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) || 1382 1367 (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B)) 1383 1368 return MODE_OK; 1384 - else if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) { 1369 + else if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector_edid(connector))) { 1385 1370 /* HDMI 1.3+ supports max clock of 340 Mhz */ 1386 1371 if (mode->clock > 340000) 1387 1372 return MODE_CLOCK_HIGH; ··· 1675 1660 (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) { 1676 1661 return radeon_dp_mode_valid_helper(connector, mode); 1677 1662 } else { 1678 - if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) { 1663 + if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector_edid(connector))) { 1679 1664 /* HDMI 1.3+ supports max clock of 340 Mhz */ 1680 1665 if (mode->clock > 340000) 1681 1666 return MODE_CLOCK_HIGH;
+1 -1
drivers/gpu/drm/radeon/radeon_display.c
··· 1691 1691 (!(mode->flags & DRM_MODE_FLAG_INTERLACE)) && 1692 1692 ((radeon_encoder->underscan_type == UNDERSCAN_ON) || 1693 1693 ((radeon_encoder->underscan_type == UNDERSCAN_AUTO) && 1694 - drm_detect_hdmi_monitor(radeon_connector->edid) && 1694 + drm_detect_hdmi_monitor(radeon_connector_edid(connector)) && 1695 1695 is_hdtv_mode(mode)))) { 1696 1696 if (radeon_encoder->underscan_hborder != 0) 1697 1697 radeon_crtc->h_border = radeon_encoder->underscan_hborder;
+2 -2
drivers/gpu/drm/radeon/radeon_encoders.c
··· 343 343 case DRM_MODE_CONNECTOR_HDMIB: 344 344 if (radeon_connector->use_digital) { 345 345 /* HDMI 1.3 supports up to 340 Mhz over single link */ 346 - if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) { 346 + if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector_edid(connector))) { 347 347 if (pixel_clock > 340000) 348 348 return true; 349 349 else ··· 365 365 return false; 366 366 else { 367 367 /* HDMI 1.3 supports up to 340 Mhz over single link */ 368 - if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) { 368 + if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector_edid(connector))) { 369 369 if (pixel_clock > 340000) 370 370 return true; 371 371 else
+2
drivers/gpu/drm/radeon/radeon_mode.h
··· 689 689 extern bool radeon_connector_is_dp12_capable(struct drm_connector *connector); 690 690 extern int radeon_get_monitor_bpc(struct drm_connector *connector); 691 691 692 + extern struct edid *radeon_connector_edid(struct drm_connector *connector); 693 + 692 694 extern void radeon_connector_hotplug(struct drm_connector *connector); 693 695 extern int radeon_dp_mode_valid_helper(struct drm_connector *connector, 694 696 struct drm_display_mode *mode);