drm/i915: Introduce intel_panel_{fixed,downclock}_mode()
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Fri, 11 Mar 2022 17:24:18 +0000 (19:24 +0200)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Mon, 14 Mar 2022 22:14:00 +0000 (00:14 +0200)
Abstract away the details on where we store the fixed/downclock
modes, and also how we select them. Will be useful for static
DRRS (aka. allowing the user to select the refresh rate for the
panel).

We pass in the user requested mode to intel_panel_fixed_mode()
so that in the future it may try to match the refresh rate.
And intel_panel_downclock_mode() gets passed the adjusted_mode
we actually chose to use so that it may find a suitable lower
resresh rate variant.

v2: Hook it up for all encoders
    s/fixed_mode/adjusted_mode/ in intel_panel_downclock_mode() (Jani)
    Elaborate on the choice or arguments for the functions (Jani)

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220311172428.14685-7-ville.syrjala@linux.intel.com
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
drivers/gpu/drm/i915/display/intel_dp.c
drivers/gpu/drm/i915/display/intel_drrs.c
drivers/gpu/drm/i915/display/intel_dsi.c
drivers/gpu/drm/i915/display/intel_dvo.c
drivers/gpu/drm/i915/display/intel_lvds.c
drivers/gpu/drm/i915/display/intel_panel.c
drivers/gpu/drm/i915/display/intel_panel.h
drivers/gpu/drm/i915/display/intel_sdvo.c

index 6195464..92a2651 100644 (file)
@@ -918,8 +918,8 @@ intel_dp_mode_valid(struct drm_connector *connector,
 {
        struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector));
        struct intel_connector *intel_connector = to_intel_connector(connector);
-       struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
        struct drm_i915_private *dev_priv = to_i915(connector->dev);
+       const struct drm_display_mode *fixed_mode;
        int target_clock = mode->clock;
        int max_rate, mode_rate, max_lanes, max_link_clock;
        int max_dotclk = dev_priv->max_dotclk_freq;
@@ -934,6 +934,7 @@ intel_dp_mode_valid(struct drm_connector *connector,
        if (mode->flags & DRM_MODE_FLAG_DBLCLK)
                return MODE_H_ILLEGAL;
 
+       fixed_mode = intel_panel_fixed_mode(intel_connector, mode);
        if (intel_dp_is_edp(intel_dp) && fixed_mode) {
                status = intel_panel_mode_valid(intel_connector, mode);
                if (status != MODE_OK)
@@ -1797,6 +1798,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
        struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+       const struct drm_display_mode *fixed_mode;
        enum port port = encoder->port;
        struct intel_connector *intel_connector = intel_dp->attached_connector;
        struct intel_digital_connector_state *intel_conn_state =
@@ -1823,7 +1825,8 @@ intel_dp_compute_config(struct intel_encoder *encoder,
        else
                pipe_config->has_audio = intel_conn_state->force_audio == HDMI_AUDIO_ON;
 
-       if (intel_dp_is_edp(intel_dp) && intel_connector->panel.fixed_mode) {
+       fixed_mode = intel_panel_fixed_mode(intel_connector, adjusted_mode);
+       if (intel_dp_is_edp(intel_dp) && fixed_mode) {
                ret = intel_panel_compute_config(intel_connector, adjusted_mode);
                if (ret)
                        return ret;
index 4afbc90..2a58bf4 100644 (file)
@@ -48,7 +48,8 @@
  */
 
 static bool can_enable_drrs(struct intel_connector *connector,
-                           const struct intel_crtc_state *pipe_config)
+                           const struct intel_crtc_state *pipe_config,
+                           const struct drm_display_mode *downclock_mode)
 {
        const struct drm_i915_private *i915 = to_i915(connector->base.dev);
 
@@ -64,7 +65,7 @@ static bool can_enable_drrs(struct intel_connector *connector,
        if (pipe_config->has_psr)
                return false;
 
-       return connector->panel.downclock_mode &&
+       return downclock_mode &&
                i915->vbt.drrs_type == DRRS_TYPE_SEAMLESS;
 }
 
@@ -75,9 +76,11 @@ intel_drrs_compute_config(struct intel_dp *intel_dp,
 {
        struct intel_connector *connector = intel_dp->attached_connector;
        struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       const struct drm_display_mode *downclock_mode =
+               intel_panel_downclock_mode(connector, &pipe_config->hw.adjusted_mode);
        int pixel_clock;
 
-       if (!can_enable_drrs(connector, pipe_config)) {
+       if (!can_enable_drrs(connector, pipe_config, downclock_mode)) {
                if (intel_cpu_transcoder_has_m2_n2(i915, pipe_config->cpu_transcoder))
                        intel_zero_m_n(&pipe_config->dp_m2_n2);
                return;
@@ -88,7 +91,7 @@ intel_drrs_compute_config(struct intel_dp *intel_dp,
 
        pipe_config->has_drrs = true;
 
-       pixel_clock = connector->panel.downclock_mode->clock;
+       pixel_clock = downclock_mode->clock;
        if (pipe_config->splitter.enable)
                pixel_clock /= pipe_config->splitter.link_count;
 
index a50422e..37f280b 100644 (file)
@@ -61,7 +61,8 @@ enum drm_mode_status intel_dsi_mode_valid(struct drm_connector *connector,
 {
        struct drm_i915_private *dev_priv = to_i915(connector->dev);
        struct intel_connector *intel_connector = to_intel_connector(connector);
-       const struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
+       const struct drm_display_mode *fixed_mode =
+               intel_panel_fixed_mode(intel_connector, mode);
        int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
        enum drm_mode_status status;
 
index 2eeb209..0367e6a 100644 (file)
@@ -226,7 +226,7 @@ intel_dvo_mode_valid(struct drm_connector *connector,
        struct intel_connector *intel_connector = to_intel_connector(connector);
        struct intel_dvo *intel_dvo = intel_attached_dvo(intel_connector);
        const struct drm_display_mode *fixed_mode =
-               intel_connector->panel.fixed_mode;
+               intel_panel_fixed_mode(intel_connector, mode);
        int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
        int target_clock = mode->clock;
 
@@ -257,9 +257,9 @@ static int intel_dvo_compute_config(struct intel_encoder *encoder,
 {
        struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
        struct intel_connector *connector = to_intel_connector(conn_state->connector);
-       const struct drm_display_mode *fixed_mode =
-               intel_dvo->attached_connector->panel.fixed_mode;
        struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
+       const struct drm_display_mode *fixed_mode =
+               intel_panel_fixed_mode(intel_dvo->attached_connector, adjusted_mode);
 
        /*
         * If we have timings from the BIOS for the panel, put them in
index dd7292d..3842417 100644 (file)
@@ -389,7 +389,8 @@ intel_lvds_mode_valid(struct drm_connector *connector,
                      struct drm_display_mode *mode)
 {
        struct intel_connector *intel_connector = to_intel_connector(connector);
-       struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
+       const struct drm_display_mode *fixed_mode =
+               intel_panel_fixed_mode(intel_connector, mode);
        int max_pixclk = to_i915(connector->dev)->max_dotclk_freq;
        enum drm_mode_status status;
 
index 6cd6d4f..3ad2467 100644 (file)
@@ -45,10 +45,25 @@ bool intel_panel_use_ssc(struct drm_i915_private *i915)
                && !(i915->quirks & QUIRK_LVDS_SSC_DISABLE);
 }
 
+const struct drm_display_mode *
+intel_panel_fixed_mode(struct intel_connector *connector,
+                      const struct drm_display_mode *mode)
+{
+       return connector->panel.fixed_mode;
+}
+
+const struct drm_display_mode *
+intel_panel_downclock_mode(struct intel_connector *connector,
+                          const struct drm_display_mode *adjusted_mode)
+{
+       return connector->panel.downclock_mode;
+}
+
 int intel_panel_compute_config(struct intel_connector *connector,
                               struct drm_display_mode *adjusted_mode)
 {
-       const struct drm_display_mode *fixed_mode = connector->panel.fixed_mode;
+       const struct drm_display_mode *fixed_mode =
+               intel_panel_fixed_mode(connector, adjusted_mode);
 
        if (!fixed_mode)
                return 0;
@@ -508,7 +523,8 @@ enum drm_mode_status
 intel_panel_mode_valid(struct intel_connector *connector,
                       const struct drm_display_mode *mode)
 {
-       const struct drm_display_mode *fixed_mode = connector->panel.fixed_mode;
+       const struct drm_display_mode *fixed_mode =
+               intel_panel_fixed_mode(connector, mode);
 
        if (!fixed_mode)
                return MODE_OK;
index d50b3f7..7ce7e99 100644 (file)
@@ -24,8 +24,12 @@ void intel_panel_fini(struct intel_panel *panel);
 enum drm_connector_status
 intel_panel_detect(struct drm_connector *connector, bool force);
 bool intel_panel_use_ssc(struct drm_i915_private *i915);
-void intel_panel_fixed_mode(const struct drm_display_mode *fixed_mode,
-                           struct drm_display_mode *adjusted_mode);
+const struct drm_display_mode *
+intel_panel_fixed_mode(struct intel_connector *connector,
+                      const struct drm_display_mode *mode);
+const struct drm_display_mode *
+intel_panel_downclock_mode(struct intel_connector *connector,
+                          const struct drm_display_mode *adjusted_mode);
 enum drm_mode_status
 intel_panel_mode_valid(struct intel_connector *connector,
                       const struct drm_display_mode *mode);
index 129f661..04487b0 100644 (file)
@@ -795,7 +795,7 @@ intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo,
 
        if (IS_LVDS(intel_sdvo_connector)) {
                const struct drm_display_mode *fixed_mode =
-                       intel_sdvo_connector->base.panel.fixed_mode;
+                       intel_panel_fixed_mode(&intel_sdvo_connector->base, mode);
 
                if (fixed_mode->hdisplay != args.width ||
                    fixed_mode->vdisplay != args.height)
@@ -1331,6 +1331,8 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
                                                           adjusted_mode);
                pipe_config->sdvo_tv_clock = true;
        } else if (IS_LVDS(intel_sdvo_connector)) {
+               const struct drm_display_mode *fixed_mode =
+                       intel_panel_fixed_mode(&intel_sdvo_connector->base, mode);
                int ret;
 
                ret = intel_panel_compute_config(&intel_sdvo_connector->base,
@@ -1338,8 +1340,7 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
                if (ret)
                        return ret;
 
-               if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo,
-                                                            intel_sdvo_connector->base.panel.fixed_mode))
+               if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, fixed_mode))
                        return -EINVAL;
 
                (void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
@@ -1461,7 +1462,7 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state,
        const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
        const struct intel_sdvo_connector_state *sdvo_state =
                to_intel_sdvo_connector_state(conn_state);
-       const struct intel_sdvo_connector *intel_sdvo_connector =
+       struct intel_sdvo_connector *intel_sdvo_connector =
                to_intel_sdvo_connector(conn_state->connector);
        const struct drm_display_mode *mode = &crtc_state->hw.mode;
        struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
@@ -1492,11 +1493,14 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state,
                return;
 
        /* lvds has a special fixed output timing. */
-       if (IS_LVDS(intel_sdvo_connector))
-               intel_sdvo_get_dtd_from_mode(&output_dtd,
-                                            intel_sdvo_connector->base.panel.fixed_mode);
-       else
+       if (IS_LVDS(intel_sdvo_connector)) {
+               const struct drm_display_mode *fixed_mode =
+                       intel_panel_fixed_mode(&intel_sdvo_connector->base, mode);
+
+               intel_sdvo_get_dtd_from_mode(&output_dtd, fixed_mode);
+       } else {
                intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
+       }
        if (!intel_sdvo_set_output_timing(intel_sdvo, &output_dtd))
                drm_info(&dev_priv->drm,
                         "Setting output timings on %s failed\n",