static void edp_fill_link_cfg(struct edp_ctrl *ctrl) { u32 prate; u32 lrate; u32 bpp; u8 max_lane = ctrl->dp_link.num_lanes; u8 lane; prate = ctrl->pixel_rate; bpp = ctrl->color_depth * 3; /* * By default, use the maximum link rate and minimum lane count, * so that we can do rate down shift during link training. */ ctrl->link_rate = drm_dp_link_rate_to_bw_code(ctrl->dp_link.rate); prate *= bpp; prate /= 8; /* in kByte */ lrate = 270000; /* in kHz */ lrate *= ctrl->link_rate; lrate /= 10; /* in kByte, 10 bits --> 8 bits */ for (lane = 1; lane <= max_lane; lane <<= 1) { if (lrate >= prate) break; lrate <<= 1; } ctrl->lane_cnt = lane; DBG("rate=%d lane=%d", ctrl->link_rate, ctrl->lane_cnt); }
/** * xilinx_drm_dp_mode_configure - Configure the link values * @dp: DisplayPort IP core structure * @pclock: pixel clock for requested display mode * * Find the link configuration values, rate and lane count for requested pixel * clock @pclock. */ static void xilinx_drm_dp_mode_configure(struct xilinx_drm_dp *dp, int pclock) { int max_rate = dp->link_config.max_rate; u8 bws[3] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7, DP_LINK_BW_5_4 }; u8 max_lanes = dp->link_config.max_lanes; u8 max_link_rate_code = drm_dp_link_rate_to_bw_code(max_rate); u8 bpp = dp->config.bpp; u8 lane_cnt, i; s8 clock; for (i = 0; i < ARRAY_SIZE(bws); i++) if (bws[i] == max_link_rate_code) break; for (lane_cnt = 1; lane_cnt <= max_lanes; lane_cnt <<= 1) for (clock = i; clock >= 0; clock--) { int bw; u32 rate; bw = drm_dp_bw_code_to_link_rate(bws[clock]); rate = xilinx_drm_dp_max_rate(bw, lane_cnt, bpp); if (pclock <= rate) { dp->mode.bw_code = bws[clock]; dp->mode.lane_cnt = lane_cnt; return; } } }
static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { struct drm_device *dev = encoder->base.dev; struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); struct intel_digital_port *intel_dig_port = intel_mst->primary; struct intel_dp *intel_dp = &intel_dig_port->dp; struct drm_atomic_state *state; int bpp, i; int lane_count, slots, rate; struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; struct drm_connector *drm_connector; struct intel_connector *connector, *found = NULL; struct drm_connector_state *connector_state; int mst_pbn; pipe_config->dp_encoder_is_mst = true; pipe_config->has_pch_encoder = false; pipe_config->has_dp_encoder = true; bpp = 24; /* * for MST we always configure max link bw - the spec doesn't * seem to suggest we should do otherwise. */ lane_count = drm_dp_max_lane_count(intel_dp->dpcd); rate = intel_dp_max_link_rate(intel_dp); if (intel_dp->num_sink_rates) { intel_dp->link_bw = 0; intel_dp->rate_select = intel_dp_rate_select(intel_dp, rate); } else { intel_dp->link_bw = drm_dp_link_rate_to_bw_code(rate); intel_dp->rate_select = 0; } intel_dp->lane_count = lane_count; pipe_config->pipe_bpp = 24; pipe_config->port_clock = rate; state = pipe_config->base.state; for_each_connector_in_state(state, drm_connector, connector_state, i) { connector = to_intel_connector(drm_connector); if (connector_state->best_encoder == &encoder->base) { found = connector; break; } }
static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info) { struct radeon_encoder *radeon_encoder = to_radeon_encoder(dp_info->encoder); struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; u8 tmp; /* power up the sink */ if (dp_info->dpcd[0] >= 0x11) { radeon_write_dpcd_reg(dp_info->radeon_connector, DP_SET_POWER, DP_SET_POWER_D0); usleep_range(1000, 2000); } /* possibly enable downspread on the sink */ if (dp_info->dpcd[3] & 0x1) radeon_write_dpcd_reg(dp_info->radeon_connector, DP_DOWNSPREAD_CTRL, DP_SPREAD_AMP_0_5); else radeon_write_dpcd_reg(dp_info->radeon_connector, DP_DOWNSPREAD_CTRL, 0); if ((dp_info->connector->connector_type == DRM_MODE_CONNECTOR_eDP) && (dig->panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) { radeon_write_dpcd_reg(dp_info->radeon_connector, DP_EDP_CONFIGURATION_SET, 1); } /* set the lane count on the sink */ tmp = dp_info->dp_lane_count; if (drm_dp_enhanced_frame_cap(dp_info->dpcd)) tmp |= DP_LANE_COUNT_ENHANCED_FRAME_EN; radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LANE_COUNT_SET, tmp); /* set the link rate on the sink */ tmp = drm_dp_link_rate_to_bw_code(dp_info->dp_clock); radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LINK_BW_SET, tmp); /* start training on the source */ if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) atombios_dig_encoder_setup(dp_info->encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_START, 0); else radeon_dp_encoder_service(dp_info->rdev, ATOM_DP_ACTION_TRAINING_START, dp_info->dp_clock, dp_info->enc_id, 0); /* disable the training pattern on the sink */ radeon_write_dpcd_reg(dp_info->radeon_connector, DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE); return 0; }
int msm_edp_ctrl_get_panel_info(struct edp_ctrl *ctrl, struct drm_connector *connector, struct edid **edid) { int ret = 0; mutex_lock(&ctrl->dev_mutex); if (ctrl->edid) { if (edid) { DBG("Just return edid buffer"); *edid = ctrl->edid; } goto unlock_ret; } if (!ctrl->power_on) { edp_ctrl_phy_aux_enable(ctrl, 1); edp_ctrl_irq_enable(ctrl, 1); } ret = drm_dp_link_probe(ctrl->drm_aux, &ctrl->dp_link); if (ret) { pr_err("%s: read dpcd cap failed, %d\n", __func__, ret); goto disable_ret; } /* Initialize link rate as panel max link rate */ ctrl->link_rate = drm_dp_link_rate_to_bw_code(ctrl->dp_link.rate); ctrl->edid = drm_get_edid(connector, &ctrl->drm_aux->ddc); if (!ctrl->edid) { pr_err("%s: edid read fail\n", __func__); goto disable_ret; } if (edid) *edid = ctrl->edid; disable_ret: if (!ctrl->power_on) { edp_ctrl_irq_enable(ctrl, 0); edp_ctrl_phy_aux_enable(ctrl, 0); } unlock_ret: mutex_unlock(&ctrl->dev_mutex); return ret; }
/** * xilinx_drm_dp_mode_configure - Configure the link values * @dp: DisplayPort IP core structure * @pclock: pixel clock for requested display mode * @current_bw: current link rate * * Find the link configuration values, rate and lane count for requested pixel * clock @pclock. * * Return: Current link rate code, or -EINVAL. */ static int xilinx_drm_dp_mode_configure(struct xilinx_drm_dp *dp, int pclock, u8 current_bw) { int max_rate = dp->link_config.max_rate; u8 bws[3] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7, DP_LINK_BW_5_4 }; u8 max_lanes = dp->link_config.max_lanes; u8 max_link_rate_code = drm_dp_link_rate_to_bw_code(max_rate); u8 bpp = dp->config.bpp; u8 lane_cnt; s8 clock, i; for (i = ARRAY_SIZE(bws) - 1; i >= 0; i--) { if (current_bw && bws[i] >= current_bw) continue; if (bws[i] <= max_link_rate_code) break; } for (lane_cnt = 1; lane_cnt <= max_lanes; lane_cnt <<= 1) for (clock = i; clock >= 0; clock--) { int bw; u32 rate; bw = drm_dp_bw_code_to_link_rate(bws[clock]); rate = xilinx_drm_dp_max_rate(bw, lane_cnt, bpp); if (pclock <= rate) { dp->mode.bw_code = bws[clock]; dp->mode.lane_cnt = lane_cnt; return bws[clock]; } } DRM_ERROR("failed to configure link values\n"); return -EINVAL; }