[Intel-gfx] [PATCH] drm/i915: introduce struct intel_crtc_config

Paulo Zanoni przanoni at gmail.com
Tue Feb 26 18:09:36 CET 2013


Hi

2013/2/22 Daniel Vetter <daniel.vetter at ffwll.ch>:
> Currently only containing the requested and the adjusted mode. And
> only crtc callbacks are converted somewhat to it, encoders will be
> done on a as-needed basis (simply too much churn in one patch
> otherwise).
>
> Future patches will add tons more useful stuff to this struct,
> starting with the very simple.
>
> v2: Store the pipe_config in the intel_crtc, so that the ->mode-set,
> ->enable and also ->disable have easy access to it.
>
> v3: Store the pipe config in the right crtc ...
>
> v4: Rebased.
>
> v5: Fixup an OOPS when trying to kfree an ERR_PTR.
>
> v6: Used drm_moode_copy and some other small cleanups as suggested
> by Ville Syrjälä.
>
> v7: drm_mode_copy preserves the mode id of the destination, so no need
> to clear it again (Ville).
>
> Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
> ---
>  drivers/gpu/drm/i915/i915_drv.h      |  4 +-
>  drivers/gpu/drm/i915/intel_display.c | 81 +++++++++++++++++++++---------------
>  drivers/gpu/drm/i915/intel_drv.h     |  7 ++++
>  3 files changed, 56 insertions(+), 36 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index e95337c..8fb14fb 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -271,6 +271,8 @@ struct drm_i915_error_state {
>         struct intel_display_error_state *display;
>  };
>
> +struct intel_crtc_config;
> +
>  struct drm_i915_display_funcs {
>         bool (*fbc_enabled)(struct drm_device *dev);
>         void (*enable_fbc)(struct drm_crtc *crtc, unsigned long interval);
> @@ -284,8 +286,6 @@ struct drm_i915_display_funcs {
>                                  struct drm_display_mode *mode);
>         void (*modeset_global_resources)(struct drm_device *dev);
>         int (*crtc_mode_set)(struct drm_crtc *crtc,
> -                            struct drm_display_mode *mode,
> -                            struct drm_display_mode *adjusted_mode,
>                              int x, int y,
>                              struct drm_framebuffer *old_fb);
>         void (*crtc_enable)(struct drm_crtc *crtc);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index b521198..a02c6a7 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3915,15 +3915,15 @@ bool intel_connector_get_hw_state(struct intel_connector *connector)
>         return encoder->get_hw_state(encoder, &pipe);
>  }
>
> -static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
> -                                 const struct drm_display_mode *mode,
> -                                 struct drm_display_mode *adjusted_mode)
> +static bool intel_crtc_compute_config(struct drm_crtc *crtc,
> +                                     struct intel_crtc_config *pipe_config)
>  {
>         struct drm_device *dev = crtc->dev;
> +       struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
>
>         if (HAS_PCH_SPLIT(dev)) {
>                 /* FDI link clock is fixed at 2.7G */
> -               if (mode->clock * 3 > IRONLAKE_FDI_FREQ * 4)
> +               if (pipe_config->requested_mode.clock * 3 > IRONLAKE_FDI_FREQ * 4)

Checkpatch.pl complains about this line (considering you've already
rejected some of my patches based on checkpatch.pl errors, I feel I
have to run checkpatch.pl on your patches too :D )

With that fixed:
Reviewed-by: Paulo Zanoni <paulo.r.zanoni at intel.com>

>                         return false;
>         }
>
> @@ -4609,14 +4609,15 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc,
>  }
>
>  static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
> -                             struct drm_display_mode *mode,
> -                             struct drm_display_mode *adjusted_mode,
>                               int x, int y,
>                               struct drm_framebuffer *fb)
>  {
>         struct drm_device *dev = crtc->dev;
>         struct drm_i915_private *dev_priv = dev->dev_private;
>         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +       struct drm_display_mode *adjusted_mode =
> +               &intel_crtc->config.adjusted_mode;
> +       struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
>         int pipe = intel_crtc->pipe;
>         int plane = intel_crtc->plane;
>         int refclk, num_connectors = 0;
> @@ -5579,14 +5580,15 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
>  }
>
>  static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> -                                 struct drm_display_mode *mode,
> -                                 struct drm_display_mode *adjusted_mode,
>                                   int x, int y,
>                                   struct drm_framebuffer *fb)
>  {
>         struct drm_device *dev = crtc->dev;
>         struct drm_i915_private *dev_priv = dev->dev_private;
>         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +       struct drm_display_mode *adjusted_mode =
> +               &intel_crtc->config.adjusted_mode;
> +       struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
>         int pipe = intel_crtc->pipe;
>         int plane = intel_crtc->plane;
>         int num_connectors = 0;
> @@ -5745,14 +5747,15 @@ static void haswell_modeset_global_resources(struct drm_device *dev)
>  }
>
>  static int haswell_crtc_mode_set(struct drm_crtc *crtc,
> -                                struct drm_display_mode *mode,
> -                                struct drm_display_mode *adjusted_mode,
>                                  int x, int y,
>                                  struct drm_framebuffer *fb)
>  {
>         struct drm_device *dev = crtc->dev;
>         struct drm_i915_private *dev_priv = dev->dev_private;
>         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +       struct drm_display_mode *adjusted_mode =
> +               &intel_crtc->config.adjusted_mode;
> +       struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
>         int pipe = intel_crtc->pipe;
>         int plane = intel_crtc->plane;
>         int num_connectors = 0;
> @@ -5829,8 +5832,6 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
>  }
>
>  static int intel_crtc_mode_set(struct drm_crtc *crtc,
> -                              struct drm_display_mode *mode,
> -                              struct drm_display_mode *adjusted_mode,
>                                int x, int y,
>                                struct drm_framebuffer *fb)
>  {
> @@ -5839,6 +5840,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
>         struct drm_encoder_helper_funcs *encoder_funcs;
>         struct intel_encoder *encoder;
>         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +       struct drm_display_mode *adjusted_mode =
> +               &intel_crtc->config.adjusted_mode;
> +       struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
>         int pipe = intel_crtc->pipe;
>         int ret;
>
> @@ -5849,8 +5853,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
>
>         drm_vblank_pre_modeset(dev, pipe);
>
> -       ret = dev_priv->display.crtc_mode_set(crtc, mode, adjusted_mode,
> -                                             x, y, fb);
> +       ret = dev_priv->display.crtc_mode_set(crtc, x, y, fb);
> +
>         drm_vblank_post_modeset(dev, pipe);
>
>         if (ret != 0)
> @@ -7478,19 +7482,22 @@ static void intel_modeset_commit_output_state(struct drm_device *dev)
>         }
>  }
>
> -static struct drm_display_mode *
> -intel_modeset_adjusted_mode(struct drm_crtc *crtc,
> -                           struct drm_display_mode *mode)
> +static struct intel_crtc_config *
> +intel_modeset_pipe_config(struct drm_crtc *crtc,
> +                         struct drm_display_mode *mode)
>  {
>         struct drm_device *dev = crtc->dev;
> -       struct drm_display_mode *adjusted_mode;
>         struct drm_encoder_helper_funcs *encoder_funcs;
>         struct intel_encoder *encoder;
> +       struct intel_crtc_config *pipe_config;
>
> -       adjusted_mode = drm_mode_duplicate(dev, mode);
> -       if (!adjusted_mode)
> +       pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
> +       if (!pipe_config)
>                 return ERR_PTR(-ENOMEM);
>
> +       drm_mode_copy(&pipe_config->adjusted_mode, mode);
> +       drm_mode_copy(&pipe_config->requested_mode, mode);
> +
>         /* Pass our mode to the connectors and the CRTC to give them a chance to
>          * adjust it according to limitations or connector properties, and also
>          * a chance to reject the mode entirely.
> @@ -7501,22 +7508,23 @@ intel_modeset_adjusted_mode(struct drm_crtc *crtc,
>                 if (&encoder->new_crtc->base != crtc)
>                         continue;
>                 encoder_funcs = encoder->base.helper_private;
> -               if (!(encoder_funcs->mode_fixup(&encoder->base, mode,
> -                                               adjusted_mode))) {
> +               if (!(encoder_funcs->mode_fixup(&encoder->base,
> +                                               &pipe_config->requested_mode,
> +                                               &pipe_config->adjusted_mode))) {
>                         DRM_DEBUG_KMS("Encoder fixup failed\n");
>                         goto fail;
>                 }
>         }
>
> -       if (!(intel_crtc_mode_fixup(crtc, mode, adjusted_mode))) {
> +       if (!(intel_crtc_compute_config(crtc, pipe_config))) {
>                 DRM_DEBUG_KMS("CRTC fixup failed\n");
>                 goto fail;
>         }
>         DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
>
> -       return adjusted_mode;
> +       return pipe_config;
>  fail:
> -       drm_mode_destroy(dev, adjusted_mode);
> +       kfree(pipe_config);
>         return ERR_PTR(-EINVAL);
>  }
>
> @@ -7782,7 +7790,8 @@ int intel_set_mode(struct drm_crtc *crtc,
>  {
>         struct drm_device *dev = crtc->dev;
>         drm_i915_private_t *dev_priv = dev->dev_private;
> -       struct drm_display_mode *adjusted_mode, *saved_mode, *saved_hwmode;
> +       struct drm_display_mode *saved_mode, *saved_hwmode;
> +       struct intel_crtc_config *pipe_config = NULL;
>         struct intel_crtc *intel_crtc;
>         unsigned disable_pipes, prepare_pipes, modeset_pipes;
>         int ret = 0;
> @@ -7809,11 +7818,12 @@ int intel_set_mode(struct drm_crtc *crtc,
>          * Hence simply check whether any bit is set in modeset_pipes in all the
>          * pieces of code that are not yet converted to deal with mutliple crtcs
>          * changing their mode at the same time. */
> -       adjusted_mode = NULL;
>         if (modeset_pipes) {
> -               adjusted_mode = intel_modeset_adjusted_mode(crtc, mode);
> -               if (IS_ERR(adjusted_mode)) {
> -                       ret = PTR_ERR(adjusted_mode);
> +               pipe_config = intel_modeset_pipe_config(crtc, mode);
> +               if (IS_ERR(pipe_config)) {
> +                       ret = PTR_ERR(pipe_config);
> +                       pipe_config = NULL;
> +
>                         goto out;
>                 }
>         }
> @@ -7826,8 +7836,12 @@ int intel_set_mode(struct drm_crtc *crtc,
>         /* crtc->mode is already used by the ->mode_set callbacks, hence we need
>          * to set it here already despite that we pass it down the callchain.
>          */
> -       if (modeset_pipes)
> +       if (modeset_pipes) {
>                 crtc->mode = *mode;
> +               /* mode_set/enable/disable functions rely on a correct pipe
> +                * config. */
> +               to_intel_crtc(crtc)->config = *pipe_config;
> +       }
>
>         /* Only after disabling all output pipelines that will be changed can we
>          * update the the output configuration. */
> @@ -7841,7 +7855,6 @@ int intel_set_mode(struct drm_crtc *crtc,
>          */
>         for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) {
>                 ret = intel_crtc_mode_set(&intel_crtc->base,
> -                                         mode, adjusted_mode,
>                                           x, y, fb);
>                 if (ret)
>                         goto done;
> @@ -7853,7 +7866,7 @@ int intel_set_mode(struct drm_crtc *crtc,
>
>         if (modeset_pipes) {
>                 /* Store real post-adjustment hardware mode. */
> -               crtc->hwmode = *adjusted_mode;
> +               crtc->hwmode = pipe_config->adjusted_mode;
>
>                 /* Calculate and store various constants which
>                  * are later needed by vblank and swap-completion
> @@ -7864,7 +7877,6 @@ int intel_set_mode(struct drm_crtc *crtc,
>
>         /* FIXME: add subpixel order */
>  done:
> -       drm_mode_destroy(dev, adjusted_mode);
>         if (ret && crtc->enabled) {
>                 crtc->hwmode = *saved_hwmode;
>                 crtc->mode = *saved_mode;
> @@ -7873,6 +7885,7 @@ done:
>         }
>
>  out:
> +       kfree(pipe_config);
>         kfree(saved_mode);
>         return ret;
>  }
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index e6f84d0..eca75b6 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -199,6 +199,11 @@ struct intel_connector {
>         struct edid *edid;
>  };
>
> +struct intel_crtc_config {
> +       struct drm_display_mode requested_mode;
> +       struct drm_display_mode adjusted_mode;
> +};
> +
>  struct intel_crtc {
>         struct drm_crtc base;
>         enum pipe pipe;
> @@ -232,6 +237,8 @@ struct intel_crtc {
>         bool cursor_visible;
>         unsigned int bpp;
>
> +       struct intel_crtc_config config;
> +
>         /* We can share PLLs across outputs if the timings match */
>         struct intel_pch_pll *pch_pll;
>         uint32_t ddi_pll_sel;
> --
> 1.7.11.4
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni



More information about the Intel-gfx mailing list