static int radeon_dp_get_dp_link_clock(struct drm_connector *connector, u8 dpcd[DP_DPCD_SIZE], int pix_clock) { int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector)); int lane_num, max_pix_clock; if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == ENCODER_OBJECT_ID_NUTMEG) return 270000; lane_num = radeon_dp_get_dp_lane_number(connector, dpcd, pix_clock); max_pix_clock = dp_get_max_dp_pix_clock(162000, lane_num, bpp); if (pix_clock <= max_pix_clock) return 162000; max_pix_clock = dp_get_max_dp_pix_clock(270000, lane_num, bpp); if (pix_clock <= max_pix_clock) return 270000; if (radeon_connector_is_dp12_capable(connector)) { max_pix_clock = dp_get_max_dp_pix_clock(540000, lane_num, bpp); if (pix_clock <= max_pix_clock) return 540000; } return drm_dp_max_link_rate(dpcd); }
static int radeon_dp_get_dp_link_clock(struct drm_connector *connector, u8 dpcd[DP_DPCD_SIZE], int pix_clock) { int bpp = convert_bpc_to_bpp(connector->display_info.bpc); int lane_num, max_pix_clock; if (radeon_connector_encoder_is_dp_bridge(connector)) return 270000; lane_num = radeon_dp_get_dp_lane_number(connector, dpcd, pix_clock); max_pix_clock = dp_get_max_dp_pix_clock(162000, lane_num, bpp); if (pix_clock <= max_pix_clock) return 162000; max_pix_clock = dp_get_max_dp_pix_clock(270000, lane_num, bpp); if (pix_clock <= max_pix_clock) return 270000; if (radeon_connector_is_dp12_capable(connector)) { max_pix_clock = dp_get_max_dp_pix_clock(540000, lane_num, bpp); if (pix_clock <= max_pix_clock) return 540000; } return dp_get_max_link_rate(dpcd); }
/* First get the min lane# when low rate is used according to pixel clock * (prefer low rate), second check max lane# supported by DP panel, * if the max lane# < low rate lane# then use max lane# instead. */ static int radeon_dp_get_dp_lane_number(struct drm_connector *connector, u8 dpcd[DP_DPCD_SIZE], int pix_clock) { int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector)); int max_link_rate = drm_dp_max_link_rate(dpcd); int max_lane_num = drm_dp_max_lane_count(dpcd); int lane_num; int max_dp_pix_clock; for (lane_num = 1; lane_num < max_lane_num; lane_num <<= 1) { max_dp_pix_clock = dp_get_max_dp_pix_clock(max_link_rate, lane_num, bpp); if (pix_clock <= max_dp_pix_clock) break; } return lane_num; }