drm/radeon/kms: fix hardcoded EDID handling

On some servers there is a hardcoded EDID provided
in the vbios so that the driver will always see a
display connected even if something like a KVM
prevents traditional means like DDC or load
detection from working properly. Also most
server boards with DVI are not actually DVI, but
DVO connected to a virtual KVM service processor.
If we fail to detect a monitor via DDC or load
detection and a hardcoded EDID is available, use
it.

Additionally, when using the hardcoded EDID, use
a copy of it rather than the actual one stored
in the driver as the detect() and get_modes()
functions may free it if DDC is successful.

This fixes the virtual KVM on several internal
servers.

Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Cc: stable@kernel.org
Signed-off-by: Dave Airlie <airlied@redhat.com>

authored by Alex Deucher and committed by Dave Airlie fafcf94e 2d370f50

+45 -7
+16 -5
drivers/gpu/drm/radeon/radeon_combios.c
··· 448 448 449 449 bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev) 450 450 { 451 - int edid_info; 451 + int edid_info, size; 452 452 struct edid *edid; 453 453 unsigned char *raw; 454 454 edid_info = combios_get_table_offset(rdev->ddev, COMBIOS_HARDCODED_EDID_TABLE); ··· 456 456 return false; 457 457 458 458 raw = rdev->bios + edid_info; 459 - edid = kmalloc(EDID_LENGTH * (raw[0x7e] + 1), GFP_KERNEL); 459 + size = EDID_LENGTH * (raw[0x7e] + 1); 460 + edid = kmalloc(size, GFP_KERNEL); 460 461 if (edid == NULL) 461 462 return false; 462 463 463 - memcpy((unsigned char *)edid, raw, EDID_LENGTH * (raw[0x7e] + 1)); 464 + memcpy((unsigned char *)edid, raw, size); 464 465 465 466 if (!drm_edid_is_valid(edid)) { 466 467 kfree(edid); ··· 469 468 } 470 469 471 470 rdev->mode_info.bios_hardcoded_edid = edid; 471 + rdev->mode_info.bios_hardcoded_edid_size = size; 472 472 return true; 473 473 } 474 474 ··· 477 475 struct edid * 478 476 radeon_bios_get_hardcoded_edid(struct radeon_device *rdev) 479 477 { 480 - if (rdev->mode_info.bios_hardcoded_edid) 481 - return rdev->mode_info.bios_hardcoded_edid; 478 + struct edid *edid; 479 + 480 + if (rdev->mode_info.bios_hardcoded_edid) { 481 + edid = kmalloc(rdev->mode_info.bios_hardcoded_edid_size, GFP_KERNEL); 482 + if (edid) { 483 + memcpy((unsigned char *)edid, 484 + (unsigned char *)rdev->mode_info.bios_hardcoded_edid, 485 + rdev->mode_info.bios_hardcoded_edid_size); 486 + return edid; 487 + } 488 + } 482 489 return NULL; 483 490 } 484 491
+28 -2
drivers/gpu/drm/radeon/radeon_connectors.c
··· 629 629 static enum drm_connector_status 630 630 radeon_vga_detect(struct drm_connector *connector, bool force) 631 631 { 632 + struct drm_device *dev = connector->dev; 633 + struct radeon_device *rdev = dev->dev_private; 632 634 struct radeon_connector *radeon_connector = to_radeon_connector(connector); 633 635 struct drm_encoder *encoder; 634 636 struct drm_encoder_helper_funcs *encoder_funcs; ··· 681 679 682 680 if (ret == connector_status_connected) 683 681 ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true); 682 + 683 + /* RN50 and some RV100 asics in servers often have a hardcoded EDID in the 684 + * vbios to deal with KVMs. If we have one and are not able to detect a monitor 685 + * by other means, assume the CRT is connected and use that EDID. 686 + */ 687 + if ((!rdev->is_atom_bios) && 688 + (ret == connector_status_disconnected) && 689 + rdev->mode_info.bios_hardcoded_edid_size) { 690 + ret = connector_status_connected; 691 + } 692 + 684 693 radeon_connector_update_scratch_regs(connector, ret); 685 694 return ret; 686 695 } ··· 803 790 static enum drm_connector_status 804 791 radeon_dvi_detect(struct drm_connector *connector, bool force) 805 792 { 793 + struct drm_device *dev = connector->dev; 794 + struct radeon_device *rdev = dev->dev_private; 806 795 struct radeon_connector *radeon_connector = to_radeon_connector(connector); 807 796 struct drm_encoder *encoder = NULL; 808 797 struct drm_encoder_helper_funcs *encoder_funcs; ··· 844 829 * you don't really know what's connected to which port as both are digital. 845 830 */ 846 831 if (radeon_connector->shared_ddc && (ret == connector_status_connected)) { 847 - struct drm_device *dev = connector->dev; 848 - struct radeon_device *rdev = dev->dev_private; 849 832 struct drm_connector *list_connector; 850 833 struct radeon_connector *list_radeon_connector; 851 834 list_for_each_entry(list_connector, &dev->mode_config.connector_list, head) { ··· 906 893 if ((ret == connector_status_connected) && (radeon_connector->use_digital == false) && 907 894 encoder) { 908 895 ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true); 896 + } 897 + 898 + /* RN50 and some RV100 asics in servers often have a hardcoded EDID in the 899 + * vbios to deal with KVMs. If we have one and are not able to detect a monitor 900 + * by other means, assume the DFP is connected and use that EDID. In most 901 + * cases the DVI port is actually a virtual KVM port connected to the service 902 + * processor. 903 + */ 904 + if ((!rdev->is_atom_bios) && 905 + (ret == connector_status_disconnected) && 906 + rdev->mode_info.bios_hardcoded_edid_size) { 907 + radeon_connector->use_digital = true; 908 + ret = connector_status_connected; 909 909 } 910 910 911 911 out:
+1
drivers/gpu/drm/radeon/radeon_mode.h
··· 239 239 struct drm_property *underscan_vborder_property; 240 240 /* hardcoded DFP edid from BIOS */ 241 241 struct edid *bios_hardcoded_edid; 242 + int bios_hardcoded_edid_size; 242 243 243 244 /* pointer to fbdev info structure */ 244 245 struct radeon_fbdev *rfbdev;