@@ -57,6 +57,7 @@
#include "display/intel_sdvo.h"
#include "display/intel_tv.h"
#include "display/intel_vdsc.h"
+#include "display/intel_vrr.h"
#include "gt/intel_rps.h"
@@ -14383,6 +14384,10 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
PIPE_CONF_CHECK_I(mst_master_transcoder);
+ PIPE_CONF_CHECK_BOOL(vrr.enable);
+ PIPE_CONF_CHECK_I(vrr.vtotalmin);
+ PIPE_CONF_CHECK_I(vrr.vtotalmax);
+
#undef PIPE_CONF_CHECK_X
#undef PIPE_CONF_CHECK_I
#undef PIPE_CONF_CHECK_BOOL
@@ -15509,6 +15514,8 @@ static int intel_atomic_check(struct drm_device *dev,
new_crtc_state->uapi.mode_changed = true;
}
+ intel_vrr_check_modeset(state);
+
ret = drm_atomic_helper_check_modeset(dev, &state->base);
if (ret)
goto fail;
@@ -1124,6 +1124,13 @@ struct intel_crtc_state {
struct intel_dsb *dsb;
u32 psr2_man_track_ctl;
+
+ /* Variable Refresh Rate state */
+ struct {
+ bool enable;
+ u16 vtotalmin;
+ u16 vtotalmax;
+ } vrr;
};
enum intel_pipe_crc_source {
@@ -2860,6 +2860,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
if (!HAS_DDI(dev_priv))
intel_dp_set_clock(encoder, pipe_config);
+ intel_vrr_compute_config(intel_dp, pipe_config);
intel_psr_compute_config(intel_dp, pipe_config);
intel_dp_drrs_compute_config(intel_dp, pipe_config, output_bpp,
constant_n);
@@ -30,3 +30,54 @@ bool intel_vrr_is_capable(struct drm_connector *connector)
info->monitor_range.max_vfreq - info->monitor_range.min_vfreq > 10;
}
+void
+intel_vrr_check_modeset(struct intel_atomic_state *state)
+{
+ int i;
+ struct intel_crtc_state *old_crtc_state, *new_crtc_state;
+ struct intel_crtc *crtc;
+
+ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
+ new_crtc_state, i) {
+ if (new_crtc_state->uapi.vrr_enabled !=
+ old_crtc_state->uapi.vrr_enabled)
+ new_crtc_state->uapi.mode_changed = true;
+ }
+}
+
+void
+intel_vrr_compute_config(struct intel_dp *intel_dp,
+ struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ struct intel_connector *intel_connector = intel_dp->attached_connector;
+ struct drm_connector *connector = &intel_connector->base;
+ struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
+ const struct drm_display_info *info = &connector->display_info;
+
+ if (!intel_vrr_is_capable(connector))
+ return;
+
+ if (!crtc_state->uapi.vrr_enabled) {
+ crtc_state->vrr.enable = false;
+ return;
+ }
+
+ crtc_state->vrr.enable = true;
+ crtc_state->vrr.vtotalmin =
+ max_t(u16, adjusted_mode->crtc_vtotal,
+ DIV_ROUND_CLOSEST(adjusted_mode->crtc_clock * 1000,
+ adjusted_mode->crtc_htotal *
+ info->monitor_range.max_vfreq));
+ crtc_state->vrr.vtotalmax =
+ max_t(u16, adjusted_mode->crtc_vtotal,
+ DIV_ROUND_UP(adjusted_mode->crtc_clock * 1000,
+ adjusted_mode->crtc_htotal *
+ info->monitor_range.min_vfreq));
+
+ drm_dbg_kms(&i915->drm,
+ "VRR Config: Enable = %s Vtotal Min = %d Vtotal Max = %d\n",
+ yesno(crtc_state->vrr.enable), crtc_state->vrr.vtotalmin,
+ crtc_state->vrr.vtotalmax);
+}
+
@@ -9,7 +9,14 @@
#include <linux/types.h>
struct drm_connector;
+struct intel_atomic_state;
+struct intel_crtc;
+struct intel_crtc_state;
+struct intel_dp;
bool intel_vrr_is_capable(struct drm_connector *connector);
+void intel_vrr_check_modeset(struct intel_atomic_state *state);
+void intel_vrr_compute_config(struct intel_dp *intel_dp,
+ struct intel_crtc_state *crtc_state);
#endif /* __INTEL_VRR_H__ */
This forces a complete modeset if vrr drm crtc state goes from enabled to disabled and vice versa. This patch also computes vrr state variables from the mode timings and based on the vrr property set by userspace as well as hardware's vrr capability. v2: *Rebase v3: * Vmin = max (vtotal, vmin) (Manasi) v4: * set crtc_state->vrr.enable = 0 for disable request v5: * drm_dbg_kms, squash crtc states def patch (Jani N) v6: * Move vrr modeset check to separate function (Jani N) Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Jani Nikula <jani.nikula@linux.intel.com> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com> --- drivers/gpu/drm/i915/display/intel_display.c | 7 +++ .../drm/i915/display/intel_display_types.h | 7 +++ drivers/gpu/drm/i915/display/intel_dp.c | 1 + drivers/gpu/drm/i915/display/intel_vrr.c | 51 +++++++++++++++++++ drivers/gpu/drm/i915/display/intel_vrr.h | 7 +++ 5 files changed, 73 insertions(+)