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 619546441eae5c325a71d3cd813f2f6833f3ea78..92a2651a71a74c4cb2cde7fe6f0e1f151baa432d 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 4afbc903f169a22e48a8f5bc79773a2e31ca4484..2a58bf4cb6cda59dbc83730ef6f2cc075d8d618c 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 a50422e03a7e89d274e9d8a271115674319a875c..37f280b1f17923b68a5f2b945e47c4547bc5bdaf 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 2eeb209afc643d27184e3840977029dd2d233416..0367e6a1bac7bebeae9423802adc3ad720b9158d 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 dd7292d3c88e7417d9341e5b76cd3040f3b12f5d..3842417e06b04d03de64631b25eb2a5316a3a36b 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 6cd6d4fdd5ad337b9e7d15fd79fb0b1a22319ddb..3ad246791da5a0f2a0e5ca567a541f349bd2ec5d 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 d50b3f7e9e58e3c1acb87e76e78419873754e2ca..7ce7e995853f46c700414d69e16107a5d7471bdc 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 129f6619c3a1ae4633765fd691499a1b3e6a0f0d..04487b03b6401e5c4ad01591edc54df993e14012 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",