In order to implement atomic mode sets, we'll need to hold state shared
by multiple crtcs in the drm_atomic_state struct. This patch moves
towards that goal by introducing struct intel_atomic_state for that
purpose and moving the staged pll configuration into it. Current state
will be moved in a follow up patch.

Signed-off-by: Ander Conselvan de Oliveira 
<ander.conselvan.de.olive...@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |   3 +-
 drivers/gpu/drm/i915/intel_ddi.c     |  11 ++--
 drivers/gpu/drm/i915/intel_display.c | 104 +++++++++++++++--------------------
 drivers/gpu/drm/i915/intel_drv.h     |   8 ++-
 4 files changed, 59 insertions(+), 67 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b09173f..862edc4 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -297,7 +297,6 @@ struct intel_shared_dpll_config {
 
 struct intel_shared_dpll {
        struct intel_shared_dpll_config config;
-       struct intel_shared_dpll_config *new_config;
 
        int active; /* count of number of active CRTCs (i.e. DPMS on) */
        bool on; /* is the PLL actually active? Disabled during modeset */
@@ -504,6 +503,7 @@ struct drm_i915_error_state {
 struct intel_connector;
 struct intel_encoder;
 struct intel_crtc_state;
+struct intel_atomic_state;
 struct intel_initial_plane_config;
 struct intel_crtc;
 struct intel_limit;
@@ -546,6 +546,7 @@ struct drm_i915_display_funcs {
        void (*get_initial_plane_config)(struct intel_crtc *,
                                         struct intel_initial_plane_config *);
        int (*crtc_compute_clock)(struct intel_crtc *crtc,
+                                 struct intel_atomic_state *state,
                                  struct intel_crtc_state *crtc_state);
        void (*crtc_enable)(struct drm_crtc *crtc);
        void (*crtc_disable)(struct drm_crtc *crtc);
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index ad8b73d..1cd541f 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -909,6 +909,7 @@ hsw_ddi_calculate_wrpll(int clock /* in Hz */,
 
 static bool
 hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
+                  struct intel_atomic_state *state,
                   struct intel_crtc_state *crtc_state,
                   struct intel_encoder *intel_encoder,
                   int clock)
@@ -926,7 +927,7 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
 
                crtc_state->dpll_hw_state.wrpll = val;
 
-               pll = intel_get_shared_dpll(intel_crtc, crtc_state);
+               pll = intel_get_shared_dpll(intel_crtc, state, crtc_state);
                if (pll == NULL) {
                        DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
                                         pipe_name(intel_crtc->pipe));
@@ -1096,6 +1097,7 @@ found:
 
 static bool
 skl_ddi_pll_select(struct intel_crtc *intel_crtc,
+                  struct intel_atomic_state *state,
                   struct intel_crtc_state *crtc_state,
                   struct intel_encoder *intel_encoder,
                   int clock)
@@ -1150,7 +1152,7 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc,
        crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
        crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
 
-       pll = intel_get_shared_dpll(intel_crtc, crtc_state);
+       pll = intel_get_shared_dpll(intel_crtc, state, crtc_state);
        if (pll == NULL) {
                DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
                                 pipe_name(intel_crtc->pipe));
@@ -1171,6 +1173,7 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc,
  * function should be folded into compute_config() eventually.
  */
 bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
+                         struct intel_atomic_state *state,
                          struct intel_crtc_state *crtc_state)
 {
        struct drm_device *dev = intel_crtc->base.dev;
@@ -1179,10 +1182,10 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
        int clock = crtc_state->port_clock;
 
        if (IS_SKYLAKE(dev))
-               return skl_ddi_pll_select(intel_crtc, crtc_state,
+               return skl_ddi_pll_select(intel_crtc, state, crtc_state,
                                          intel_encoder, clock);
        else
-               return hsw_ddi_pll_select(intel_crtc, crtc_state,
+               return hsw_ddi_pll_select(intel_crtc, state, crtc_state,
                                          intel_encoder, clock);
 }
 
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 3d220a6..159e6c8 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3891,6 +3891,7 @@ void intel_put_shared_dpll(struct intel_crtc *crtc)
 }
 
 struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
+                                               struct intel_atomic_state 
*state,
                                                struct intel_crtc_state 
*crtc_state)
 {
        struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
@@ -3905,7 +3906,7 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct 
intel_crtc *crtc,
                DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
                              crtc->base.base.id, pll->name);
 
-               WARN_ON(pll->new_config->crtc_mask);
+               WARN_ON(state->shared_dpll[i].crtc_mask);
 
                goto found;
        }
@@ -3914,15 +3915,15 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct 
intel_crtc *crtc,
                pll = &dev_priv->shared_dplls[i];
 
                /* Only want to check enabled timings first */
-               if (pll->new_config->crtc_mask == 0)
+               if (state->shared_dpll[i].crtc_mask == 0)
                        continue;
 
                if (memcmp(&crtc_state->dpll_hw_state,
-                          &pll->new_config->hw_state,
-                          sizeof(pll->new_config->hw_state)) == 0) {
+                          &state->shared_dpll[i].hw_state,
+                          sizeof(state->shared_dpll[i].hw_state)) == 0) {
                        DRM_DEBUG_KMS("CRTC:%d sharing existing %s (crtc mask 
0x%08x, ative %d)\n",
                                      crtc->base.base.id, pll->name,
-                                     pll->new_config->crtc_mask,
+                                     state->shared_dpll[i].crtc_mask,
                                      pll->active);
                        goto found;
                }
@@ -3931,7 +3932,7 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct 
intel_crtc *crtc,
        /* Ok no matching timings, maybe there's a free one? */
        for (i = 0; i < dev_priv->num_shared_dpll; i++) {
                pll = &dev_priv->shared_dplls[i];
-               if (pll->new_config->crtc_mask == 0) {
+               if (state->shared_dpll[i].crtc_mask == 0) {
                        DRM_DEBUG_KMS("CRTC:%d allocated %s\n",
                                      crtc->base.base.id, pll->name);
                        goto found;
@@ -3941,14 +3942,14 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct 
intel_crtc *crtc,
        return NULL;
 
 found:
-       if (pll->new_config->crtc_mask == 0)
-               pll->new_config->hw_state = crtc_state->dpll_hw_state;
+       if (state->shared_dpll[i].crtc_mask == 0)
+               state->shared_dpll[i].hw_state = crtc_state->dpll_hw_state;
 
        crtc_state->shared_dpll = i;
        DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name,
                         pipe_name(crtc->pipe));
 
-       pll->new_config->crtc_mask |= 1 << crtc->pipe;
+       state->shared_dpll[i].crtc_mask |= 1 << crtc->pipe;
 
        return pll;
 }
@@ -3962,6 +3963,7 @@ found:
  * releasing the references of pipes specified in clear_pipes.
  */
 static int intel_shared_dpll_start_config(struct drm_i915_private *dev_priv,
+                                         struct intel_atomic_state *state,
                                          unsigned clear_pipes)
 {
        struct intel_shared_dpll *pll;
@@ -3970,54 +3972,23 @@ static int intel_shared_dpll_start_config(struct 
drm_i915_private *dev_priv,
        for (i = 0; i < dev_priv->num_shared_dpll; i++) {
                pll = &dev_priv->shared_dplls[i];
 
-               pll->new_config = kmemdup(&pll->config, sizeof pll->config,
-                                         GFP_KERNEL);
-               if (!pll->new_config)
-                       goto cleanup;
-
-               pll->new_config->crtc_mask &= ~clear_pipes;
+               memcpy(&state->shared_dpll[i], &pll->config,
+                      sizeof pll->config);
+               state->shared_dpll[i].crtc_mask &= ~clear_pipes;
        }
 
        return 0;
-
-cleanup:
-       while (--i >= 0) {
-               pll = &dev_priv->shared_dplls[i];
-               kfree(pll->new_config);
-               pll->new_config = NULL;
-       }
-
-       return -ENOMEM;
 }
 
-static void intel_shared_dpll_commit(struct drm_i915_private *dev_priv)
+static void intel_shared_dpll_commit(struct drm_i915_private *dev_priv,
+                                    struct intel_atomic_state *state)
 {
        struct intel_shared_dpll *pll;
        enum intel_dpll_id i;
 
        for (i = 0; i < dev_priv->num_shared_dpll; i++) {
                pll = &dev_priv->shared_dplls[i];
-
-               WARN_ON(pll->new_config == &pll->config);
-
-               pll->config = *pll->new_config;
-               kfree(pll->new_config);
-               pll->new_config = NULL;
-       }
-}
-
-static void intel_shared_dpll_abort_config(struct drm_i915_private *dev_priv)
-{
-       struct intel_shared_dpll *pll;
-       enum intel_dpll_id i;
-
-       for (i = 0; i < dev_priv->num_shared_dpll; i++) {
-               pll = &dev_priv->shared_dplls[i];
-
-               WARN_ON(pll->new_config == &pll->config);
-
-               kfree(pll->new_config);
-               pll->new_config = NULL;
+               pll->config = state->shared_dpll[i];
        }
 }
 
@@ -6426,6 +6397,7 @@ static void i9xx_set_pipeconf(struct intel_crtc 
*intel_crtc)
 }
 
 static int i9xx_crtc_compute_clock(struct intel_crtc *crtc,
+                                  struct intel_atomic_state *state,
                                   struct intel_crtc_state *crtc_state)
 {
        struct drm_device *dev = crtc->base.dev;
@@ -7452,6 +7424,7 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc 
*intel_crtc,
 }
 
 static int ironlake_crtc_compute_clock(struct intel_crtc *crtc,
+                                      struct intel_atomic_state *state,
                                       struct intel_crtc_state *crtc_state)
 {
        struct drm_device *dev = crtc->base.dev;
@@ -7498,7 +7471,7 @@ static int ironlake_crtc_compute_clock(struct intel_crtc 
*crtc,
                else
                        crtc_state->dpll_hw_state.fp1 = fp;
 
-               pll = intel_get_shared_dpll(crtc, crtc_state);
+               pll = intel_get_shared_dpll(crtc, state, crtc_state);
                if (pll == NULL) {
                        DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
                                         pipe_name(crtc->pipe));
@@ -8070,9 +8043,10 @@ void hsw_disable_pc8(struct drm_i915_private *dev_priv)
 }
 
 static int haswell_crtc_compute_clock(struct intel_crtc *crtc,
+                                     struct intel_atomic_state *state,
                                      struct intel_crtc_state *crtc_state)
 {
-       if (!intel_ddi_pll_select(crtc, crtc_state))
+       if (!intel_ddi_pll_select(crtc, state, crtc_state))
                return -EINVAL;
 
        crtc->lowfreq_avail = false;
@@ -10417,14 +10391,15 @@ static bool intel_crtc_in_use(struct drm_crtc *crtc)
 }
 
 static void
-intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes)
+intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes,
+                          struct intel_atomic_state *state)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_encoder *intel_encoder;
        struct intel_crtc *intel_crtc;
        struct drm_connector *connector;
 
-       intel_shared_dpll_commit(dev_priv);
+       intel_shared_dpll_commit(dev_priv, state);
 
        for_each_intel_encoder(dev, intel_encoder) {
                if (!intel_encoder->base.crtc)
@@ -11022,6 +10997,7 @@ out:
 }
 
 static int __intel_set_mode_setup_plls(struct drm_device *dev,
+                                      struct intel_atomic_state *state,
                                       unsigned modeset_pipes,
                                       unsigned disable_pipes)
 {
@@ -11033,21 +11009,18 @@ static int __intel_set_mode_setup_plls(struct 
drm_device *dev,
        if (!dev_priv->display.crtc_compute_clock)
                return 0;
 
-       ret = intel_shared_dpll_start_config(dev_priv, clear_pipes);
+       ret = intel_shared_dpll_start_config(dev_priv, state, clear_pipes);
        if (ret)
-               goto done;
+               return ret;
 
        for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) {
-               struct intel_crtc_state *state = intel_crtc->new_config;
+               struct intel_crtc_state *crtc_state = intel_crtc->new_config;
                ret = dev_priv->display.crtc_compute_clock(intel_crtc,
-                                                          state);
-               if (ret) {
-                       intel_shared_dpll_abort_config(dev_priv);
-                       goto done;
-               }
+                                                          state, crtc_state);
+               if (ret)
+                       break;
        }
 
-done:
        return ret;
 }
 
@@ -11063,6 +11036,7 @@ static int __intel_set_mode(struct drm_crtc *crtc,
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_display_mode *saved_mode;
        struct intel_crtc *intel_crtc;
+       struct intel_atomic_state *state = NULL;
        int ret = 0;
 
        saved_mode = kmalloc(sizeof(*saved_mode), GFP_KERNEL);
@@ -11088,7 +11062,14 @@ static int __intel_set_mode(struct drm_crtc *crtc,
                prepare_pipes &= ~disable_pipes;
        }
 
-       ret = __intel_set_mode_setup_plls(dev, modeset_pipes, disable_pipes);
+       state = kzalloc(sizeof *state, GFP_KERNEL);
+       if (!state) {
+               ret = -ENOMEM;
+               goto done;
+       }
+
+       ret = __intel_set_mode_setup_plls(dev, state,
+                                         modeset_pipes, disable_pipes);
        if (ret)
                goto done;
 
@@ -11124,7 +11105,7 @@ static int __intel_set_mode(struct drm_crtc *crtc,
 
        /* Only after disabling all output pipelines that will be changed can we
         * update the the output configuration. */
-       intel_modeset_update_state(dev, prepare_pipes);
+       intel_modeset_update_state(dev, prepare_pipes, state);
 
        modeset_update_crtc_power_domains(dev);
 
@@ -11155,6 +11136,7 @@ done:
        if (ret && crtc->enabled)
                crtc->mode = *saved_mode;
 
+       kfree(state);
        kfree(saved_mode);
        return ret;
 }
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index eef79cc..f2f4210 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -243,6 +243,10 @@ typedef struct dpll {
        int     p;
 } intel_clock_t;
 
+struct intel_atomic_state {
+       struct intel_shared_dpll_config shared_dpll[I915_NUM_PLLS];
+};
+
 struct intel_plane_state {
        struct drm_plane_state base;
        struct drm_rect src;
@@ -837,6 +841,7 @@ void intel_ddi_disable_transcoder_func(struct 
drm_i915_private *dev_priv,
 void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc);
 void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc);
 bool intel_ddi_pll_select(struct intel_crtc *crtc,
+                         struct intel_atomic_state *state,
                          struct intel_crtc_state *crtc_state);
 void intel_ddi_set_pipe_settings(struct drm_crtc *crtc);
 void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder);
@@ -962,7 +967,8 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
 #define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true)
 #define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false)
 struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
-                                               struct intel_crtc_state *state);
+                                               struct intel_atomic_state 
*state,
+                                               struct intel_crtc_state 
*crtc_state);
 void intel_put_shared_dpll(struct intel_crtc *crtc);
 
 void vlv_force_pll_on(struct drm_device *dev, enum pipe pipe,
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to