diff mbox series

[3/4] drm/i915/display/dp: Compute VRR state in atomic_check

Message ID 20200826190657.18283-3-manasi.d.navare@intel.com (mailing list archive)
State New, archived
Headers show
Series [1/4] drm/i915/display/dp: Attach and set drm connector VRR property | expand

Commit Message

Navare, Manasi Aug. 26, 2020, 7:06 p.m. UTC
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.

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 | 12 +++++--
 drivers/gpu/drm/i915/display/intel_dp.c      | 33 ++++++++++++++++++++
 2 files changed, 43 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index c8b1dd1a9e46..4caa4cb16b5c 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -14033,6 +14033,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
@@ -14899,7 +14903,9 @@  static int intel_atomic_check(struct drm_device *dev,
 
 	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
 					    new_crtc_state, i) {
-		if (!needs_modeset(new_crtc_state)) {
+		if (!needs_modeset(new_crtc_state) &&
+		    old_crtc_state->uapi.vrr_enabled ==
+		    new_crtc_state->uapi.vrr_enabled) {
 			/* Light copy */
 			intel_crtc_copy_uapi_to_hw_state_nomodeset(new_crtc_state);
 
@@ -14920,7 +14926,9 @@  static int intel_atomic_check(struct drm_device *dev,
 
 	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
 					    new_crtc_state, i) {
-		if (!needs_modeset(new_crtc_state))
+		if (!needs_modeset(new_crtc_state) &&
+		    old_crtc_state->uapi.vrr_enabled ==
+		    new_crtc_state->uapi.vrr_enabled)
 			continue;
 
 		ret = intel_modeset_pipe_config_late(new_crtc_state);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 3a7129a8ca8a..af2f8fc4f9b1 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2575,6 +2575,38 @@  intel_dp_compute_hdr_metadata_infoframe_sdp(struct intel_dp *intel_dp,
 		intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GAMUT_METADATA);
 }
 
+static void
+intel_dp_vrr_config(struct intel_dp *intel_dp,
+		    struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *dev_priv = 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_dp_is_vrr_capable(connector) ||
+	    !crtc_state->uapi.vrr_enabled)
+		return;
+
+	crtc_state->vrr.enable = true;
+	crtc_state->vrr.vtotalmin =
+		min_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_info(&dev_priv->drm,
+		 "VRR Config: Enable = %s Vtotal Min = %d Vtotal Max = %d",
+		 yesno(crtc_state->vrr.enable), crtc_state->vrr.vtotalmin,
+		 crtc_state->vrr.vtotalmax);
+}
+
 int
 intel_dp_compute_config(struct intel_encoder *encoder,
 			struct intel_crtc_state *pipe_config,
@@ -2671,6 +2703,7 @@  intel_dp_compute_config(struct intel_encoder *encoder,
 	if (!HAS_DDI(dev_priv))
 		intel_dp_set_clock(encoder, pipe_config);
 
+	intel_dp_vrr_config(intel_dp, pipe_config);
 	intel_psr_compute_config(intel_dp, pipe_config);
 	intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);
 	intel_dp_compute_hdr_metadata_infoframe_sdp(intel_dp, pipe_config, conn_state);