i915/dp/fec: Add fec_enable to the crtc state.
authorAnusha Srivatsa <anusha.srivatsa@intel.com>
Wed, 28 Nov 2018 20:26:25 +0000 (12:26 -0800)
committerManasi Navare <manasi.d.navare@intel.com>
Thu, 29 Nov 2018 20:32:46 +0000 (12:32 -0800)
For DP 1.4 and above, Display Stream compression can be
enabled only if Forward Error Correctin can be performed.

Add a crtc state for FEC. Currently, the state
is determined by platform, DP and DSC being
enabled. Moving forward we can use the state
to have error correction on other scenarios too
if needed.

v2:
- Control compression_enable with the fec_enable
parameter in crtc state and with intel_dp_supports_fec()
(Ville)

- intel_dp_can_fec()/intel_dp_supports_fec()(manasi)

v3: Check for FEC support along with setting crtc state.

v4: add checks to intel_dp_source_supports_dsc.(manasi)
- Move intel_dp_supports_fec() closer to
intel_dp_supports_dsc() (Anusha)

v5: Move fec check to intel_dp_supports_dsc(Ville)

v6: Remove warning. rebase.

v7: change crtc state to include DP sink and fec capability
of source.(Manasi)

v8: Set fec_enable in crtc in intel_dp_compute_config().

v9 (From Manasi):
* Combine the !edp and !fec_support check
* Derive dev_priv from intel_dp directly

v10 (From Manasi):
* Rebase

Suggested-by: Ville Syrjala <ville.syrjala@linux.intel.com>
Cc: dri-devel@lists.freedesktop.org
Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Manasi Navare <manasi.d.navare@intel.com>
Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.comk>
Reviewed-by: Manasi Navare <manasi.d.navare@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181128202628.20238-14-manasi.d.navare@intel.com
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h

index 4e65dd1a6c073a655af1515020e51b7931f6fe8a..38a6e82153fdc76e67f0923c1d3faf662a1983d5 100644 (file)
@@ -545,7 +545,7 @@ intel_dp_mode_valid(struct drm_connector *connector,
                        dsc_slice_count =
                                drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
                                                                true);
-               } else {
+               } else if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) {
                        dsc_max_output_bpp =
                                intel_dp_dsc_get_output_bpp(max_link_clock,
                                                            max_lanes,
@@ -1710,14 +1710,26 @@ struct link_config_limits {
        int min_bpp, max_bpp;
 };
 
-static bool intel_dp_source_supports_dsc(struct intel_dp *intel_dp,
+static bool intel_dp_source_supports_fec(struct intel_dp *intel_dp,
                                         const struct intel_crtc_state *pipe_config)
 {
        struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
-       /* FIXME: FEC needed for external DP until then reject DSC on DP */
-       if (!intel_dp_is_edp(intel_dp))
-               return false;
+       return INTEL_GEN(dev_priv) >= 11 &&
+               pipe_config->cpu_transcoder != TRANSCODER_A;
+}
+
+static bool intel_dp_supports_fec(struct intel_dp *intel_dp,
+                                 const struct intel_crtc_state *pipe_config)
+{
+       return intel_dp_source_supports_fec(intel_dp, pipe_config) &&
+               drm_dp_sink_supports_fec(intel_dp->fec_capable);
+}
+
+static bool intel_dp_source_supports_dsc(struct intel_dp *intel_dp,
+                                        const struct intel_crtc_state *pipe_config)
+{
+       struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
        return INTEL_GEN(dev_priv) >= 10 &&
                pipe_config->cpu_transcoder != TRANSCODER_A;
@@ -1726,6 +1738,9 @@ static bool intel_dp_source_supports_dsc(struct intel_dp *intel_dp,
 static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
                                  const struct intel_crtc_state *pipe_config)
 {
+       if (!intel_dp_is_edp(intel_dp) && !pipe_config->fec_enable)
+               return false;
+
        return intel_dp_source_supports_dsc(intel_dp, pipe_config) &&
                drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd);
 }
@@ -2129,6 +2144,9 @@ intel_dp_compute_config(struct intel_encoder *encoder,
        if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
                return false;
 
+       pipe_config->fec_enable = !intel_dp_is_edp(intel_dp) &&
+                                 intel_dp_supports_fec(intel_dp, pipe_config);
+
        if (!intel_dp_compute_link_config(encoder, pipe_config, conn_state))
                return false;
 
index 0623dc8ab115d112af369f72d7d8b63aa8ccc586..86ff57738cd91529adf040ee421568e03ee1e294 100644 (file)
@@ -951,6 +951,9 @@ struct intel_crtc_state {
                u8 slice_count;
        } dsc_params;
        struct drm_dsc_config dp_dsc_cfg;
+
+       /* Forward Error correction State */
+       bool fec_enable;
 };
 
 struct intel_crtc {