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