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

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=80691Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 72a5c970
...@@ -716,7 +716,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) ...@@ -716,7 +716,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
if (radeon_connector->use_digital && if (radeon_connector->use_digital &&
(radeon_connector->audio == RADEON_AUDIO_ENABLE)) (radeon_connector->audio == RADEON_AUDIO_ENABLE))
return ATOM_ENCODER_MODE_HDMI; 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)) (radeon_connector->audio == RADEON_AUDIO_AUTO))
return ATOM_ENCODER_MODE_HDMI; return ATOM_ENCODER_MODE_HDMI;
else if (radeon_connector->use_digital) else if (radeon_connector->use_digital)
...@@ -735,7 +735,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) ...@@ -735,7 +735,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
if (radeon_audio != 0) { if (radeon_audio != 0) {
if (radeon_connector->audio == RADEON_AUDIO_ENABLE) if (radeon_connector->audio == RADEON_AUDIO_ENABLE)
return ATOM_ENCODER_MODE_HDMI; 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)) (radeon_connector->audio == RADEON_AUDIO_AUTO))
return ATOM_ENCODER_MODE_HDMI; return ATOM_ENCODER_MODE_HDMI;
else else
...@@ -755,7 +755,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) ...@@ -755,7 +755,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
} else if (radeon_audio != 0) { } else if (radeon_audio != 0) {
if (radeon_connector->audio == RADEON_AUDIO_ENABLE) if (radeon_connector->audio == RADEON_AUDIO_ENABLE)
return ATOM_ENCODER_MODE_HDMI; 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)) (radeon_connector->audio == RADEON_AUDIO_AUTO))
return ATOM_ENCODER_MODE_HDMI; return ATOM_ENCODER_MODE_HDMI;
else else
......
...@@ -175,7 +175,7 @@ void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder) ...@@ -175,7 +175,7 @@ void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder)
return; 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) { if (sad_count <= 0) {
DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
return; return;
...@@ -238,7 +238,7 @@ void dce6_afmt_write_sad_regs(struct drm_encoder *encoder) ...@@ -238,7 +238,7 @@ void dce6_afmt_write_sad_regs(struct drm_encoder *encoder)
return; 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) { if (sad_count <= 0) {
DRM_ERROR("Couldn't read SADs: %d\n", sad_count); DRM_ERROR("Couldn't read SADs: %d\n", sad_count);
return; return;
......
...@@ -117,7 +117,7 @@ static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder) ...@@ -117,7 +117,7 @@ static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder)
return; 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) { if (sad_count <= 0) {
DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
return; return;
...@@ -172,7 +172,7 @@ static void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder) ...@@ -172,7 +172,7 @@ static void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder)
return; 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) { if (sad_count <= 0) {
DRM_ERROR("Couldn't read SADs: %d\n", sad_count); DRM_ERROR("Couldn't read SADs: %d\n", sad_count);
return; return;
......
...@@ -107,7 +107,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector) ...@@ -107,7 +107,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector)
case DRM_MODE_CONNECTOR_DVII: case DRM_MODE_CONNECTOR_DVII:
case DRM_MODE_CONNECTOR_HDMIB: case DRM_MODE_CONNECTOR_HDMIB:
if (radeon_connector->use_digital) { 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) if (connector->display_info.bpc)
bpc = connector->display_info.bpc; bpc = connector->display_info.bpc;
} }
...@@ -115,7 +115,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector) ...@@ -115,7 +115,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector)
break; break;
case DRM_MODE_CONNECTOR_DVID: case DRM_MODE_CONNECTOR_DVID:
case DRM_MODE_CONNECTOR_HDMIA: 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) if (connector->display_info.bpc)
bpc = connector->display_info.bpc; bpc = connector->display_info.bpc;
} }
...@@ -124,7 +124,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector) ...@@ -124,7 +124,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector)
dig_connector = radeon_connector->con_priv; dig_connector = radeon_connector->con_priv;
if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
(dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) || (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) if (connector->display_info.bpc)
bpc = connector->display_info.bpc; bpc = connector->display_info.bpc;
} }
...@@ -148,7 +148,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector) ...@@ -148,7 +148,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector)
break; 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+ */ /* hdmi deep color only implemented on DCE4+ */
if ((bpc > 8) && !ASIC_IS_DCE4(rdev)) { if ((bpc > 8) && !ASIC_IS_DCE4(rdev)) {
DRM_DEBUG("%s: HDMI deep color %d bpc unsupported. Using 8 bpc.\n", 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, ...@@ -262,6 +262,21 @@ static struct drm_encoder *radeon_find_encoder(struct drm_connector *connector,
return NULL; 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) static void radeon_connector_get_edid(struct drm_connector *connector)
{ {
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
...@@ -1366,7 +1381,7 @@ static int radeon_dvi_mode_valid(struct drm_connector *connector, ...@@ -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_DUAL_LINK_DVI_D) ||
(radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B)) (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B))
return MODE_OK; 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 */ /* HDMI 1.3+ supports max clock of 340 Mhz */
if (mode->clock > 340000) if (mode->clock > 340000)
return MODE_CLOCK_HIGH; return MODE_CLOCK_HIGH;
...@@ -1660,7 +1675,7 @@ static int radeon_dp_mode_valid(struct drm_connector *connector, ...@@ -1660,7 +1675,7 @@ static int radeon_dp_mode_valid(struct drm_connector *connector,
(radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) { (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {
return radeon_dp_mode_valid_helper(connector, mode); return radeon_dp_mode_valid_helper(connector, mode);
} else { } 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 */ /* HDMI 1.3+ supports max clock of 340 Mhz */
if (mode->clock > 340000) if (mode->clock > 340000)
return MODE_CLOCK_HIGH; return MODE_CLOCK_HIGH;
......
...@@ -1691,7 +1691,7 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, ...@@ -1691,7 +1691,7 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
(!(mode->flags & DRM_MODE_FLAG_INTERLACE)) && (!(mode->flags & DRM_MODE_FLAG_INTERLACE)) &&
((radeon_encoder->underscan_type == UNDERSCAN_ON) || ((radeon_encoder->underscan_type == UNDERSCAN_ON) ||
((radeon_encoder->underscan_type == UNDERSCAN_AUTO) && ((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)))) { is_hdtv_mode(mode)))) {
if (radeon_encoder->underscan_hborder != 0) if (radeon_encoder->underscan_hborder != 0)
radeon_crtc->h_border = radeon_encoder->underscan_hborder; radeon_crtc->h_border = radeon_encoder->underscan_hborder;
......
...@@ -343,7 +343,7 @@ bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder, ...@@ -343,7 +343,7 @@ bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder,
case DRM_MODE_CONNECTOR_HDMIB: case DRM_MODE_CONNECTOR_HDMIB:
if (radeon_connector->use_digital) { if (radeon_connector->use_digital) {
/* HDMI 1.3 supports up to 340 Mhz over single link */ /* HDMI 1.3 supports up to 340 Mhz over single link */
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))) {
if (pixel_clock > 340000) if (pixel_clock > 340000)
return true; return true;
else else
...@@ -365,7 +365,7 @@ bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder, ...@@ -365,7 +365,7 @@ bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder,
return false; return false;
else { else {
/* HDMI 1.3 supports up to 340 Mhz over single link */ /* HDMI 1.3 supports up to 340 Mhz over single link */
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))) {
if (pixel_clock > 340000) if (pixel_clock > 340000)
return true; return true;
else else
......
...@@ -689,6 +689,8 @@ extern bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector); ...@@ -689,6 +689,8 @@ extern bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector);
extern bool radeon_connector_is_dp12_capable(struct drm_connector *connector); extern bool radeon_connector_is_dp12_capable(struct drm_connector *connector);
extern int radeon_get_monitor_bpc(struct drm_connector *connector); extern int radeon_get_monitor_bpc(struct drm_connector *connector);
extern struct edid *radeon_connector_edid(struct drm_connector *connector);
extern void radeon_connector_hotplug(struct drm_connector *connector); extern void radeon_connector_hotplug(struct drm_connector *connector);
extern int radeon_dp_mode_valid_helper(struct drm_connector *connector, extern int radeon_dp_mode_valid_helper(struct drm_connector *connector,
struct drm_display_mode *mode); struct drm_display_mode *mode);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment