Revert "drm/rockchip: calculate lanes and rate for Main Link Lanes"

This reverts commit 7dd63e4010.

Signed-off-by: Guochun Huang <hero.huang@rock-chips.com>
Change-Id: If587600bc616c841cd2ce2be94e5aee289170149
This commit is contained in:
Guochun Huang
2020-06-01 16:02:47 +08:00
committed by Tao Huang
parent 79e0f95365
commit 5f31e9caba
5 changed files with 38 additions and 106 deletions

View File

@@ -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;

View File

@@ -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;
};

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);