On Mon, 01 Jun 2015, Maarten Lankhorst <[email protected]> 
wrote:
> From: Ander Conselvan de Oliveira <[email protected]>
>
> Now that we can subclass drm_atomic_state we can also use it to keep
> track of all the pll settings. atomic_state is a better place to hold
> all shared state than keeping pll->new_config everywhere.
>
> Changes since v1:
> - Assert connection_mutex is held.
>
> Signed-off-by: Ander Conselvan de Oliveira 
> <[email protected]>
> Signed-off-by: Maarten Lankhorst <[email protected]>
> Reviewed-by: Matt Roper <[email protected]>
> ---
>  drivers/gpu/drm/i915/i915_drv.h      |   1 -
>  drivers/gpu/drm/i915/intel_atomic.c  |  51 ++++++++++++++++
>  drivers/gpu/drm/i915/intel_display.c | 111 
> +++++++++++------------------------
>  drivers/gpu/drm/i915/intel_drv.h     |  13 ++++
>  4 files changed, 97 insertions(+), 79 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 862bb9d4b08d..0cdc81c0e6e1 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -376,7 +376,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 */
> diff --git a/drivers/gpu/drm/i915/intel_atomic.c 
> b/drivers/gpu/drm/i915/intel_atomic.c
> index 7ed8033aae60..6ab82dc56cea 100644
> --- a/drivers/gpu/drm/i915/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> @@ -421,3 +421,54 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
>  
>       return 0;
>  }
> +
> +static void
> +intel_atomic_duplicate_dpll_state(struct drm_i915_private *dev_priv,
> +                               struct intel_shared_dpll_config *shared_dpll)
> +{
> +     enum intel_dpll_id i;
> +
> +     /* Copy shared dpll state */
> +     for (i = 0; i < dev_priv->num_shared_dpll; i++) {
> +             struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
> +
> +             shared_dpll[i] = pll->config;
> +     }
> +}
> +
> +struct intel_shared_dpll_config *
> +intel_atomic_get_shared_dpll_state(struct drm_atomic_state *s)
> +{
> +     struct intel_atomic_state *state = to_intel_atomic_state(s);
> +
> +     WARN_ON(!drm_modeset_is_locked(&s->dev->mode_config.connection_mutex));
> +
> +     if (!state->dpll_set) {
> +             state->dpll_set = true;
> +
> +             intel_atomic_duplicate_dpll_state(to_i915(s->dev),
> +                                               state->shared_dpll);
> +     }
> +
> +     return state->shared_dpll;
> +}
> +
> +struct drm_atomic_state *
> +intel_atomic_state_alloc(struct drm_device *dev)
> +{
> +     struct intel_atomic_state *state = kzalloc(GFP_KERNEL, sizeof(*state));

The kzalloc parameters are the wrong way around.

Sparse would've told you:

  CHECK   drivers/gpu/drm/i915/intel_atomic.c
drivers/gpu/drm/i915/intel_atomic.c:459:52: warning: incorrect type in argument 
1 (different base types)
drivers/gpu/drm/i915/intel_atomic.c:459:52:    expected unsigned long 
[unsigned] [usertype] size
drivers/gpu/drm/i915/intel_atomic.c:459:52:    got restricted gfp_t
drivers/gpu/drm/i915/intel_atomic.c:459:64: warning: incorrect type in argument 
2 (different base types)
drivers/gpu/drm/i915/intel_atomic.c:459:64:    expected restricted gfp_t 
[usertype] flags
drivers/gpu/drm/i915/intel_atomic.c:459:64:    got unsigned long

BR,
Jani.


> +
> +     if (!state || drm_atomic_state_init(dev, &state->base) < 0) {
> +             kfree(state);
> +             return NULL;
> +     }
> +
> +     return &state->base;
> +}
> +
> +void intel_atomic_state_clear(struct drm_atomic_state *s)
> +{
> +     struct intel_atomic_state *state = to_intel_atomic_state(s);
> +     drm_atomic_state_default_clear(&state->base);
> +     state->dpll_set = false;
> +}
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index 3ec324651b8a..3538a1059db0 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4186,8 +4186,11 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct 
> intel_crtc *crtc,
>  {
>       struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
>       struct intel_shared_dpll *pll;
> +     struct intel_shared_dpll_config *shared_dpll;
>       enum intel_dpll_id i;
>  
> +     shared_dpll = 
> intel_atomic_get_shared_dpll_state(crtc_state->base.state);
> +
>       if (HAS_PCH_IBX(dev_priv->dev)) {
>               /* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
>               i = (enum intel_dpll_id) crtc->pipe;
> @@ -4196,7 +4199,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(shared_dpll[i].crtc_mask);
>  
>               goto found;
>       }
> @@ -4216,7 +4219,7 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct 
> intel_crtc *crtc,
>               pll = &dev_priv->shared_dplls[i];
>               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(shared_dpll[i].crtc_mask);
>  
>               goto found;
>       }
> @@ -4225,15 +4228,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 (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) {
> +                        &shared_dpll[i].hw_state,
> +                        sizeof(crtc_state->dpll_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,
> +                                   shared_dpll[i].crtc_mask,
>                                     pll->active);
>                       goto found;
>               }
> @@ -4242,7 +4245,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 (shared_dpll[i].crtc_mask == 0) {
>                       DRM_DEBUG_KMS("CRTC:%d allocated %s\n",
>                                     crtc->base.base.id, pll->name);
>                       goto found;
> @@ -4252,83 +4255,33 @@ 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 (shared_dpll[i].crtc_mask == 0)
> +             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;
> +     shared_dpll[i].crtc_mask |= 1 << crtc->pipe;
>  
>       return pll;
>  }
>  
> -/**
> - * intel_shared_dpll_start_config - start a new PLL staged config
> - * @dev_priv: DRM device
> - * @clear_pipes: mask of pipes that will have their PLLs freed
> - *
> - * Starts a new PLL staged config, copying the current config but
> - * releasing the references of pipes specified in clear_pipes.
> - */
> -static int intel_shared_dpll_start_config(struct drm_i915_private *dev_priv,
> -                                       unsigned clear_pipes)
> -{
> -     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];
> -
> -             pll->new_config = kmemdup(&pll->config, sizeof pll->config,
> -                                       GFP_KERNEL);
> -             if (!pll->new_config)
> -                     goto cleanup;
> -
> -             pll->new_config->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_atomic_state *state)
>  {
> +     struct drm_i915_private *dev_priv = to_i915(state->dev);
> +     struct intel_shared_dpll_config *shared_dpll;
>       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;
> +     if (!to_intel_atomic_state(state)->dpll_set)
> +             return;
>  
> +     shared_dpll = to_intel_atomic_state(state)->shared_dpll;
>       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 = shared_dpll[i];
>       }
>  }
>  
> @@ -11975,13 +11928,12 @@ static void
>  intel_modeset_update_state(struct drm_atomic_state *state)
>  {
>       struct drm_device *dev = state->dev;
> -     struct drm_i915_private *dev_priv = dev->dev_private;
>       struct intel_encoder *intel_encoder;
>       struct drm_crtc *crtc;
>       struct drm_crtc_state *crtc_state;
>       struct drm_connector *connector;
>  
> -     intel_shared_dpll_commit(dev_priv);
> +     intel_shared_dpll_commit(state);
>       drm_atomic_helper_swap_state(state->dev, state);
>  
>       for_each_intel_encoder(dev, intel_encoder) {
> @@ -12610,9 +12562,13 @@ static int __intel_set_mode_setup_plls(struct 
> drm_atomic_state *state)
>               }
>       }
>  
> -     ret = intel_shared_dpll_start_config(dev_priv, clear_pipes);
> -     if (ret)
> -             goto done;
> +     if (clear_pipes) {
> +             struct intel_shared_dpll_config *shared_dpll =
> +                     intel_atomic_get_shared_dpll_state(state);
> +
> +             for (i = 0; i < dev_priv->num_shared_dpll; i++)
> +                     shared_dpll[i].crtc_mask &= ~clear_pipes;
> +     }
>  
>       for_each_crtc_in_state(state, crtc, crtc_state, i) {
>               if (!needs_modeset(crtc_state) || !crtc_state->enable)
> @@ -12623,13 +12579,10 @@ static int __intel_set_mode_setup_plls(struct 
> drm_atomic_state *state)
>  
>               ret = dev_priv->display.crtc_compute_clock(intel_crtc,
>                                                          intel_crtc_state);
> -             if (ret) {
> -                     intel_shared_dpll_abort_config(dev_priv);
> -                     goto done;
> -             }
> +             if (ret)
> +                     return ret;
>       }
>  
> -done:
>       return ret;
>  }
>  
> @@ -14324,6 +14277,8 @@ static const struct drm_mode_config_funcs 
> intel_mode_funcs = {
>       .output_poll_changed = intel_fbdev_output_poll_changed,
>       .atomic_check = intel_atomic_check,
>       .atomic_commit = intel_atomic_commit,
> +     .atomic_state_alloc = intel_atomic_state_alloc,
> +     .atomic_state_clear = intel_atomic_state_clear,
>  };
>  
>  /* Set up chip specific display functions */
> diff --git a/drivers/gpu/drm/i915/intel_drv.h 
> b/drivers/gpu/drm/i915/intel_drv.h
> index b9082fd16792..ddae28ac4e6f 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -241,6 +241,13 @@ typedef struct dpll {
>       int     p;
>  } intel_clock_t;
>  
> +struct intel_atomic_state {
> +     struct drm_atomic_state base;
> +
> +     bool dpll_set;
> +     struct intel_shared_dpll_config shared_dpll[I915_NUM_PLLS];
> +};
> +
>  struct intel_plane_state {
>       struct drm_plane_state base;
>       struct drm_rect src;
> @@ -628,6 +635,7 @@ struct cxsr_latency {
>       unsigned long cursor_hpll_disable;
>  };
>  
> +#define to_intel_atomic_state(x) container_of(x, struct intel_atomic_state, 
> base)
>  #define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
>  #define to_intel_crtc_state(x) container_of(x, struct intel_crtc_state, base)
>  #define to_intel_connector(x) container_of(x, struct intel_connector, base)
> @@ -1405,6 +1413,11 @@ int intel_connector_atomic_get_property(struct 
> drm_connector *connector,
>  struct drm_crtc_state *intel_crtc_duplicate_state(struct drm_crtc *crtc);
>  void intel_crtc_destroy_state(struct drm_crtc *crtc,
>                              struct drm_crtc_state *state);
> +struct drm_atomic_state *intel_atomic_state_alloc(struct drm_device *dev);
> +void intel_atomic_state_clear(struct drm_atomic_state *);
> +struct intel_shared_dpll_config *
> +intel_atomic_get_shared_dpll_state(struct drm_atomic_state *s);
> +
>  static inline struct intel_crtc_state *
>  intel_atomic_get_crtc_state(struct drm_atomic_state *state,
>                           struct intel_crtc *crtc)
> -- 
> 2.1.0
>
> _______________________________________________
> Intel-gfx mailing list
> [email protected]
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to