/** * 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 int xilinx_drm_dp_mode_valid(struct drm_encoder *encoder, struct drm_display_mode *mode) { struct xilinx_drm_dp *dp = to_dp(encoder); u8 max_lanes = dp->link_config.max_lanes; u8 bpp = dp->config.bpp; int max_rate = dp->link_config.max_rate; int rate; if (mode->clock > XILINX_DP_MAX_CLOCK) return MODE_CLOCK_HIGH; rate = xilinx_drm_dp_max_rate(max_rate, max_lanes, bpp); if (mode->clock > rate) return MODE_CLOCK_HIGH; return MODE_OK; }
/** * 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; }