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

drm/radeon/kms: improve bpc handling (v2)

Improve handling of bpc (bits per color) in radeon.
In most cases we want 8 except for HDMI, DP, LVDS, and eDP.

v2: handle DP better.

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Tested-by: Lennert Buytenhek <buytenh@wantstofly.org>
Signed-off-by: Dave Airlie <airlied@redhat.com>

authored by

Alex Deucher and committed by
Dave Airlie
eccea792 9923777d

+63 -12
+2 -5
drivers/gpu/drm/radeon/atombios_crtc.c
··· 588 588 if (encoder->crtc == crtc) { 589 589 radeon_encoder = to_radeon_encoder(encoder); 590 590 connector = radeon_get_connector_for_encoder(encoder); 591 - /* if (connector && connector->display_info.bpc) 592 - bpc = connector->display_info.bpc; */ 591 + bpc = radeon_get_monitor_bpc(connector); 593 592 encoder_mode = atombios_get_encoder_mode(encoder); 594 593 is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock); 595 594 if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || ··· 964 965 struct radeon_connector_atom_dig *dig_connector = 965 966 radeon_connector->con_priv; 966 967 int dp_clock; 967 - 968 - /* if (connector->display_info.bpc) 969 - bpc = connector->display_info.bpc; */ 968 + bpc = radeon_get_monitor_bpc(connector); 970 969 971 970 switch (encoder_mode) { 972 971 case ATOM_ENCODER_MODE_DP_MST:
+2 -5
drivers/gpu/drm/radeon/atombios_dp.c
··· 405 405 /* get bpc from the EDID */ 406 406 static int convert_bpc_to_bpp(int bpc) 407 407 { 408 - #if 0 409 408 if (bpc == 0) 410 409 return 24; 411 410 else 412 411 return bpc * 3; 413 - #endif 414 - return 24; 415 412 } 416 413 417 414 /* get the max pix clock supported by the link rate and lane num */ ··· 460 463 u8 dpcd[DP_DPCD_SIZE], 461 464 int pix_clock) 462 465 { 463 - int bpp = convert_bpc_to_bpp(connector->display_info.bpc); 466 + int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector)); 464 467 int max_link_rate = dp_get_max_link_rate(dpcd); 465 468 int max_lane_num = dp_get_max_lane_number(dpcd); 466 469 int lane_num; ··· 479 482 u8 dpcd[DP_DPCD_SIZE], 480 483 int pix_clock) 481 484 { 482 - int bpp = convert_bpc_to_bpp(connector->display_info.bpc); 485 + int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector)); 483 486 int lane_num, max_pix_clock; 484 487 485 488 if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) ==
+2 -2
drivers/gpu/drm/radeon/atombios_encoders.c
··· 541 541 dp_clock = dig_connector->dp_clock; 542 542 dp_lane_count = dig_connector->dp_lane_count; 543 543 hpd_id = radeon_connector->hpd.hpd; 544 - /* bpc = connector->display_info.bpc; */ 544 + bpc = radeon_get_monitor_bpc(connector); 545 545 } 546 546 547 547 /* no dig encoder assigned */ ··· 1159 1159 dp_lane_count = dig_connector->dp_lane_count; 1160 1160 connector_object_id = 1161 1161 (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; 1162 - /* bpc = connector->display_info.bpc; */ 1162 + bpc = radeon_get_monitor_bpc(connector); 1163 1163 } 1164 1164 1165 1165 memset(&args, 0, sizeof(args));
+56
drivers/gpu/drm/radeon/radeon_connectors.c
··· 84 84 crtc->x, crtc->y, crtc->fb); 85 85 } 86 86 } 87 + 88 + int radeon_get_monitor_bpc(struct drm_connector *connector) 89 + { 90 + struct drm_device *dev = connector->dev; 91 + struct radeon_device *rdev = dev->dev_private; 92 + struct radeon_connector *radeon_connector = to_radeon_connector(connector); 93 + struct radeon_connector_atom_dig *dig_connector; 94 + int bpc = 8; 95 + 96 + switch (connector->connector_type) { 97 + case DRM_MODE_CONNECTOR_DVII: 98 + case DRM_MODE_CONNECTOR_HDMIB: 99 + if (radeon_connector->use_digital) { 100 + if (drm_detect_hdmi_monitor(radeon_connector->edid)) { 101 + if (connector->display_info.bpc) 102 + bpc = connector->display_info.bpc; 103 + } 104 + } 105 + break; 106 + case DRM_MODE_CONNECTOR_DVID: 107 + case DRM_MODE_CONNECTOR_HDMIA: 108 + if (drm_detect_hdmi_monitor(radeon_connector->edid)) { 109 + if (connector->display_info.bpc) 110 + bpc = connector->display_info.bpc; 111 + } 112 + break; 113 + case DRM_MODE_CONNECTOR_DisplayPort: 114 + dig_connector = radeon_connector->con_priv; 115 + if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || 116 + (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) || 117 + drm_detect_hdmi_monitor(radeon_connector->edid)) { 118 + if (connector->display_info.bpc) 119 + bpc = connector->display_info.bpc; 120 + } 121 + break; 122 + case DRM_MODE_CONNECTOR_eDP: 123 + case DRM_MODE_CONNECTOR_LVDS: 124 + if (connector->display_info.bpc) 125 + bpc = connector->display_info.bpc; 126 + else if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { 127 + struct drm_connector_helper_funcs *connector_funcs = 128 + connector->helper_private; 129 + struct drm_encoder *encoder = connector_funcs->best_encoder(connector); 130 + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 131 + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; 132 + 133 + if (dig->lcd_misc & ATOM_PANEL_MISC_V13_6BIT_PER_COLOR) 134 + bpc = 6; 135 + else if (dig->lcd_misc & ATOM_PANEL_MISC_V13_8BIT_PER_COLOR) 136 + bpc = 8; 137 + } 138 + break; 139 + } 140 + return bpc; 141 + } 142 + 87 143 static void 88 144 radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_connector_status status) 89 145 {
+1
drivers/gpu/drm/radeon/radeon_mode.h
··· 476 476 extern u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector); 477 477 extern bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector); 478 478 extern bool radeon_connector_is_dp12_capable(struct drm_connector *connector); 479 + extern int radeon_get_monitor_bpc(struct drm_connector *connector); 479 480 480 481 extern void radeon_connector_hotplug(struct drm_connector *connector); 481 482 extern int radeon_dp_mode_valid_helper(struct drm_connector *connector,