[RFC PATCH 16/18] drm/i915: Filtering media playback DRRS requests

Ramalingam C
2015-06-26T14:00:43Z

If the platform supports the media playback DRRS, Userspace can provide
a request for Media playback DRRS. This is done by placing the modeset
request with the same mode and FB but with different vrefresh.

This change implements the algorithm to identify the Media playback
DRRS requests from the normal modeset requests.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 14 +++++++++
drivers/gpu/drm/i915/intel_drrs.c | 54 ++++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/intel_drrs.h | 1 +
3 files changed, 69 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index b36fde6..0335c09 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13295,6 +13295,20 @@ static int intel_crtc_set_config(struct drm_mode_set *set)

dev = set->crtc->dev;

+ /* Identifying the Media Playback DRRS request */
+ if (is_media_playback_drrs_request(set)) {
+
+ /*
+ * While requesting for Media Playback DRRS Userspace should
+ * make sure that fb passed is same as that is in use.
+ * Else at successful drrs request, we will hit a warn_on on
+ * return path for fb mismatch
+ */
+ ret = intel_media_playback_drrs_configure(
+ to_intel_crtc(set->crtc), set->mode);
+ return ret;
+ }
+
state = drm_atomic_state_alloc(dev);
if (!state)
return -ENOMEM;
diff --git a/drivers/gpu/drm/i915/intel_drrs.c b/drivers/gpu/drm/i915/intel_drrs.c
index 7f66be4..9634254 100644
--- a/drivers/gpu/drm/i915/intel_drrs.c
+++ b/drivers/gpu/drm/i915/intel_drrs.c
@@ -523,6 +523,60 @@ set_state:
return 0;
}

+/* Function to filter the Media playback DRRS request from the normal
+ * mode set */
+bool is_media_playback_drrs_request(struct drm_mode_set *set)
+{
+ struct drm_device *dev = set->crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(set->crtc);
+ struct i915_drrs *drrs;
+ struct intel_encoder *encoder;
+ struct drrs_info *drrs_state;
+ bool ret = false;
+ int index;
+
+ index = get_drrs_struct_index_for_crtc(dev_priv, intel_crtc);
+ if (index < 0)
+ return ret;
+
+ drrs = dev_priv->drrs[index];
+ if (!drrs || !drrs->has_drrs)
+ return ret;
+
+ /* Return if the current crtc mode's vrefresh is 0 */
+ if (!set->mode || !set->crtc->mode.vrefresh)
+ return ret;
+
+ /* Crtc should be active */
+ if (!intel_crtc->active)
+ return ret;
+
+ drrs_state = &drrs->drrs_state;
+ encoder = drrs->connector->encoder;
+
+ /* At present only DSI and eDP support DRRS */
+ if (encoder->type != INTEL_OUTPUT_EDP &&
+ encoder->type != INTEL_OUTPUT_DSI)
+ return ret;
+
+ DRM_DEBUG_KMS("mode_vr: %d, crtc_vr: %d, cur_rr_type: %d\n",
+ set->mode->vrefresh, set->crtc->mode.vrefresh,
+ drrs_state->current_rr_type);
+
+ if (drm_mode_equal_no_clocks_no_stereo(set->mode, &set->crtc->mode)) {
+ if (set->mode->vrefresh != set->crtc->mode.vrefresh)
+ ret = true;
+
+ if (drrs_state->type == SEAMLESS_DRRS_SUPPORT_SW &&
+ drrs->encoder_ops->is_mp_drrs_req)
+ if (drrs->encoder_ops->is_mp_drrs_req(drrs, set->mode))
+ ret = true;
+ }
+
+ return ret;
+}
+
/* Idleness detection logic is initialized */
int intel_drrs_idleness_detection_init(struct i915_drrs *drrs)
{
diff --git a/drivers/gpu/drm/i915/intel_drrs.h b/drivers/gpu/drm/i915/intel_drrs.h
index 7f9985c0..72b4aeb 100644
--- a/drivers/gpu/drm/i915/intel_drrs.h
+++ b/drivers/gpu/drm/i915/intel_drrs.h
@@ -30,6 +30,7 @@ void intel_disable_idleness_drrs(struct i915_drrs *drrs);
void intel_enable_idleness_drrs(struct i915_drrs *drrs);
int intel_media_playback_drrs_configure(struct intel_crtc *crtc,
struct drm_display_mode *mode);
+bool is_media_playback_drrs_request(struct drm_mode_set *set);
int intel_drrs_init(struct drm_device *dev,
struct intel_connector *intel_connector,
struct drm_display_mode *fixed_mode);