drm/rockchip: analogix_dp: support vrr

Signed-off-by: Zhang Yubing <yubing.zhang@rock-chips.com>
Change-Id: I17de7401b9da853cd49b0da34abd77385272824d
This commit is contained in:
Zhang Yubing
2022-07-23 15:12:46 +08:00
committed by Tao Huang
parent d2ebeecddd
commit b10a10d25e
2 changed files with 53 additions and 0 deletions

View File

@@ -313,6 +313,23 @@ static int analogix_dp_training_pattern_dis(struct analogix_dp_device *dp)
return ret < 0 ? ret : 0;
}
static bool analogix_dp_get_vrr_capable(struct analogix_dp_device *dp)
{
struct drm_connector *connector = &dp->connector;
struct drm_display_info *info = &connector->display_info;
if (!info->monitor_range.max_vfreq)
return false;
if (!info->monitor_range.min_vfreq)
return false;
if (info->monitor_range.max_vfreq < info->monitor_range.min_vfreq)
return false;
if (!drm_dp_sink_can_do_video_without_timing_msa(dp->dpcd))
return false;
return true;
}
static int analogix_dp_link_start(struct analogix_dp_device *dp)
{
u8 buf[4];
@@ -339,6 +356,8 @@ static int analogix_dp_link_start(struct analogix_dp_device *dp)
/* Spread AMP if required, enable 8b/10b coding */
buf[0] = analogix_dp_ssc_supported(dp) ? DP_SPREAD_AMP_0_5 : 0;
if (analogix_dp_get_vrr_capable(dp))
buf[0] |= DP_MSA_TIMING_PAR_IGNORE_EN;
buf[1] = DP_SET_ANSI_8B10B;
retval = drm_dp_dpcd_write(&dp->aux, DP_DOWNSPREAD_CTRL, buf, 2);
if (retval < 0)

View File

@@ -89,6 +89,9 @@ struct rockchip_dp_device {
struct analogix_dp_device *adp;
struct analogix_dp_plat_data plat_data;
struct rockchip_drm_sub_dev sub_dev;
unsigned int min_refresh_rate;
unsigned int max_refresh_rate;
};
static int rockchip_grf_write(struct regmap *grf, unsigned int reg,
@@ -394,6 +397,7 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder,
struct rockchip_dp_device *dp = to_dp(encoder);
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
struct drm_display_info *di = &conn_state->connector->display_info;
int refresh_rate;
if (di->num_bus_formats)
s->bus_format = di->bus_formats[0];
@@ -422,6 +426,33 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder,
s->tv_state = &conn_state->tv;
s->eotf = HDMI_EOTF_TRADITIONAL_GAMMA_SDR;
s->color_space = V4L2_COLORSPACE_DEFAULT;
/**
* It's priority to user rate range define in dtsi.
*/
if (dp->max_refresh_rate && dp->min_refresh_rate) {
s->max_refresh_rate = dp->max_refresh_rate;
s->min_refresh_rate = dp->min_refresh_rate;
} else {
s->max_refresh_rate = di->monitor_range.max_vfreq;
s->min_refresh_rate = di->monitor_range.min_vfreq;
}
/**
* Timing exposed in DisplayID or legacy EDID is usually optimized
* for bandwidth by using minimum horizontal and vertical blank. If
* timing beyond the Adaptive-Sync range, it should not enable the
* Ignore MSA option in this timing. If the refresh rate of the
* timing is with the Adaptive-Sync range, this timing should support
* the Adaptive-Sync from the timing's refresh rate to minimum
* support range.
*/
refresh_rate = drm_mode_vrefresh(&crtc_state->adjusted_mode);
if (refresh_rate > s->max_refresh_rate || refresh_rate < s->min_refresh_rate) {
s->max_refresh_rate = 0;
s->min_refresh_rate = 0;
} else if (refresh_rate < s->max_refresh_rate) {
s->max_refresh_rate = refresh_rate;
}
return 0;
}
@@ -626,6 +657,9 @@ static int rockchip_dp_probe(struct platform_device *pdev)
secondary->plat_data.split_mode = true;
}
device_property_read_u32(dev, "min-refresh-rate", &dp->min_refresh_rate);
device_property_read_u32(dev, "max-refresh-rate", &dp->max_refresh_rate);
return component_add(dev, &rockchip_dp_component_ops);
}