diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c index 3514f230d315..30104912e249 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c @@ -313,6 +313,9 @@ static int cdn_dp_connector_mode_valid(struct drm_connector *connector, break; } + if (!IS_ALIGNED(mode->hdisplay * bpc * 3, 32)) + return MODE_H_ILLEGAL; + requested = mode->clock * bpc * 3 / 1000; source_max = dp->lanes; diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h b/drivers/gpu/drm/rockchip/cdn-dp-core.h index b3788168fef1..77a97934b4e9 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.h +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h @@ -109,9 +109,6 @@ struct cdn_dp_device { int active_port; u8 train_set[4]; - u8 tu_size; - u64 tu_symbol; - u8 dpcd[DP_RECEIVER_CAP_SIZE]; bool sink_has_audio; }; diff --git a/drivers/gpu/drm/rockchip/cdn-dp-link-training.c b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c index 4292a4c5a74d..08962e96b17c 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-link-training.c +++ b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c @@ -355,66 +355,12 @@ static int cdn_dp_get_lower_link_rate(struct cdn_dp_device *dp) return 0; } -static int cdn_dp_main_link_config_cal(struct cdn_dp_device *dp) -{ - struct drm_display_info *display_info = &dp->connector.display_info; - struct drm_display_mode *mode = &dp->mode; - u32 rate, require_cap, bit_rate_cap, sink_max, source_max; - u8 num_lanes[] = {1, 2, 4}; - u16 link_rate[] = {1620, 2700, 5400}; - u8 bpc, x, y; - int ret; - - switch (display_info->bpc) { - case 10: - bpc = 10; - break; - case 6: - bpc = 6; - break; - default: - bpc = 8; - break; - } - - require_cap = mode->clock / 1000 * bpc * 3; - source_max = dp->lanes; - sink_max = drm_dp_max_lane_count(dp->dpcd); - dp->link.num_lanes = min(source_max, sink_max); - source_max = drm_dp_bw_code_to_link_rate(CDN_DP_MAX_LINK_RATE); - sink_max = drm_dp_max_link_rate(dp->dpcd); - rate = min(source_max, sink_max); - dp->link.rate = drm_dp_link_rate_to_bw_code(rate); - - for (y = 0; y < ARRAY_SIZE(link_rate) && - link_rate[y] <= rate / 100; y++) { - for (x = 0; x < ARRAY_SIZE(num_lanes) && - num_lanes[x] <= dp->link.num_lanes; x++) { - bit_rate_cap = link_rate[y] * num_lanes[x] * 8 / 10; - if (require_cap < bit_rate_cap) { - rate = drm_dp_link_rate_to_bw_code( - link_rate[y] * 100); - ret = cdn_dp_tu_size_cal(dp, - num_lanes[x], rate); - if (ret) - continue; - dp->link.num_lanes = num_lanes[x]; - dp->link.rate = rate; - dev_info(dp->dev, "%dMbps x %dlanes\n", - link_rate[y], dp->link.num_lanes); - return ret; - } - } - } - ret = cdn_dp_tu_size_cal(dp, dp->link.num_lanes, dp->link.rate); - return ret; -} - int cdn_dp_software_train_link(struct cdn_dp_device *dp) { struct cdn_dp_port *port = dp->port[dp->active_port]; int ret, stop_err; u8 link_config[2]; + u32 rate, sink_max, source_max; bool ssc_on; ret = drm_dp_dpcd_read(&dp->aux, DP_DPCD_REV, dp->dpcd, @@ -424,11 +370,14 @@ int cdn_dp_software_train_link(struct cdn_dp_device *dp) return ret; } - ret = cdn_dp_main_link_config_cal(dp); - if (ret) { - DRM_DEV_ERROR(dp->dev, "Failed to cal TU_SIZE %d\n", ret); - return ret; - } + source_max = dp->lanes; + sink_max = drm_dp_max_lane_count(dp->dpcd); + dp->link.num_lanes = min(source_max, sink_max); + + source_max = drm_dp_bw_code_to_link_rate(CDN_DP_MAX_LINK_RATE); + sink_max = drm_dp_max_link_rate(dp->dpcd); + rate = min(source_max, sink_max); + dp->link.rate = drm_dp_link_rate_to_bw_code(rate); ssc_on = !!(dp->dpcd[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5); link_config[0] = ssc_on ? DP_SPREAD_AMP_0_5 : 0; diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.c b/drivers/gpu/drm/rockchip/cdn-dp-reg.c index c30174f40310..f243f1eddd38 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-reg.c +++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.c @@ -713,52 +713,13 @@ static int cdn_dp_get_msa_misc(struct video_info *video, return msa_misc; } -int cdn_dp_tu_size_cal(struct cdn_dp_device *dp, u8 lanes, u8 link_bw) -{ - struct video_info *video = &dp->video_info; - struct drm_display_mode *mode = &dp->mode; - u8 bit_per_pix, tu_size_reg = TU_SIZE; - u32 link_rate, rem; - u64 symbol; - int ret; - - bit_per_pix = (video->color_fmt == YCBCR_4_2_2) ? - (video->color_depth * 2) : (video->color_depth * 3); - - link_rate = drm_dp_bw_code_to_link_rate(link_bw) / 1000; - - /* - * get a best tu_size and valid symbol: - * 1. chose Lclk freq(162Mhz, 270Mhz, 540Mhz), set TU to 32 - * 2. calculate VS(valid symbol) = TU * Pclk * Bpp / (Lclk * Lanes) - * 3. if VS > *.85 or VS < *.1 or VS < 2 or TU < VS + 4, then set - * TU += 2 and repeat 2nd step. - */ - do { - tu_size_reg += 2; - symbol = tu_size_reg * mode->clock * bit_per_pix; - do_div(symbol, lanes * link_rate * 8); - rem = do_div(symbol, 1000); - if (tu_size_reg > 64) { - ret = -EINVAL; - return ret; - } - } while ((symbol <= 1) || (tu_size_reg - symbol < 4) || - (rem > 850) || (rem < 100)); - - dp->tu_size = tu_size_reg; - dp->tu_symbol = symbol; - return 0; -} - int cdn_dp_config_video(struct cdn_dp_device *dp) { struct video_info *video = &dp->video_info; struct drm_display_mode *mode = &dp->mode; - u8 tu_size_reg = dp->tu_size; - u64 symbol = dp->tu_symbol; - u32 val, link_rate; - u8 bit_per_pix; + u64 symbol; + u32 val, link_rate, rem; + u8 bit_per_pix, tu_size_reg = TU_SIZE; int ret; bit_per_pix = (video->color_fmt == YCBCR_4_2_2) ? @@ -774,6 +735,29 @@ int cdn_dp_config_video(struct cdn_dp_device *dp) if (ret) goto err_config_video; + /* + * get a best tu_size and valid symbol: + * 1. chose Lclk freq(162Mhz, 270Mhz, 540Mhz), set TU to 32 + * 2. calculate VS(valid symbol) = TU * Pclk * Bpp / (Lclk * Lanes) + * 3. if VS > *.85 or VS < *.1 or VS < 2 or TU < VS + 4, then set + * TU += 2 and repeat 2nd step. + */ + do { + tu_size_reg += 2; + symbol = tu_size_reg * mode->clock * bit_per_pix; + do_div(symbol, dp->link.num_lanes * link_rate * 8); + rem = do_div(symbol, 1000); + if (tu_size_reg > 64) { + ret = -EINVAL; + DRM_DEV_ERROR(dp->dev, + "tu error, clk:%d, lanes:%d, rate:%d\n", + mode->clock, dp->link.num_lanes, + link_rate); + goto err_config_video; + } + } while ((symbol <= 1) || (tu_size_reg - symbol < 4) || + (rem > 850) || (rem < 100)); + val = symbol + (tu_size_reg << 8); val |= TU_CNT_RST_EN; ret = cdn_dp_reg_write(dp, DP_FRAMER_TU, val); diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.h b/drivers/gpu/drm/rockchip/cdn-dp-reg.h index 03759d02a3c3..0d01d153ed61 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-reg.h +++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.h @@ -534,7 +534,6 @@ int cdn_dp_get_edid_block(void *dp, u8 *edid, unsigned int block, size_t length); int cdn_dp_train_link(struct cdn_dp_device *dp); int cdn_dp_set_video_status(struct cdn_dp_device *dp, int active); -int cdn_dp_tu_size_cal(struct cdn_dp_device *dp, u8 lanes, u8 link_bw); int cdn_dp_config_video(struct cdn_dp_device *dp); int cdn_dp_audio_stop(struct cdn_dp_device *dp, struct audio_info *audio); int cdn_dp_audio_mute(struct cdn_dp_device *dp, bool enable);