On Sun, 19 Aug 2012 21:12:34 +0200 Daniel Vetter <daniel.vetter at ffwll.ch> wrote: > Together with the static helper functions drm_crtc_prepare_encoders > and drm_encoder_disable (which will be simplified in the next patch, > but for now are 1:1 copies). Again, no changes beside new names for > these functions. > > Also call our new set_mode instead of the crtc helper one now in all > the places we've done so far. > > v2: Call the function just intel_set_mode to better differentia it > from intel_crtc_mode_set which really only does the ->mode_set step of > the entire modeset sequence on one crtc. Whereas this function does > the global change. > > Signed-Off-by: Daniel Vetter <daniel.vetter at ffwll.ch> > --- > drivers/gpu/drm/i915/intel_display.c | 162 +++++++++++++++++++++++++++++++++-- > drivers/gpu/drm/i915/intel_dp.c | 5 +- > drivers/gpu/drm/i915/intel_drv.h | 2 + > drivers/gpu/drm/i915/intel_hdmi.c | 5 +- > drivers/gpu/drm/i915/intel_lvds.c | 4 +- > drivers/gpu/drm/i915/intel_sdvo.c | 4 +- > drivers/gpu/drm/i915/intel_tv.c | 4 +- > 7 files changed, 168 insertions(+), 18 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > index 9d5c575..3e119a6 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -5767,7 +5767,7 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, > goto fail; > } > > - if (!drm_crtc_helper_set_mode(crtc, mode, 0, 0, old_fb)) { > + if (!intel_set_mode(crtc, mode, 0, 0, old_fb)) { > DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n"); > if (old->release_fb) > old->release_fb->funcs->destroy(old->release_fb); > @@ -6635,6 +6635,157 @@ intel_crtc_helper_disable(struct drm_crtc *crtc) > return 0; > } > > +static void > +intel_encoder_disable_helper(struct drm_encoder *encoder) > +{ > + struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; > + > + if (encoder_funcs->disable) > + (*encoder_funcs->disable)(encoder); > + else > + (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); > +} > + > +static void > +intel_crtc_prepare_encoders(struct drm_device *dev) > +{ > + struct drm_encoder_helper_funcs *encoder_funcs; > + struct drm_encoder *encoder; > + > + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { > + encoder_funcs = encoder->helper_private; > + /* Disable unused encoders */ > + if (encoder->crtc == NULL) > + intel_encoder_disable_helper(encoder); > + /* Disable encoders whose CRTC is about to change */ > + if (encoder_funcs->get_crtc && > + encoder->crtc != (*encoder_funcs->get_crtc)(encoder)) > + intel_encoder_disable_helper(encoder); > + } > +} > + > +bool intel_set_mode(struct drm_crtc *crtc, > + struct drm_display_mode *mode, > + int x, int y, struct drm_framebuffer *old_fb) > +{ > + struct drm_device *dev = crtc->dev; > + struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode; > + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; > + struct drm_encoder_helper_funcs *encoder_funcs; > + int saved_x, saved_y; > + struct drm_encoder *encoder; > + bool ret = true; > + > + crtc->enabled = drm_helper_crtc_in_use(crtc); > + if (!crtc->enabled) > + return true; > + > + adjusted_mode = drm_mode_duplicate(dev, mode); > + if (!adjusted_mode) > + return false; > + > + saved_hwmode = crtc->hwmode; > + saved_mode = crtc->mode; > + saved_x = crtc->x; > + saved_y = crtc->y; > + > + /* Update crtc values up front so the driver can rely on them for mode > + * setting. > + */ > + crtc->mode = *mode; > + crtc->x = x; > + crtc->y = y; > + > + /* 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. > + */ > + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { > + > + if (encoder->crtc != crtc) > + continue; > + encoder_funcs = encoder->helper_private; > + if (!(ret = encoder_funcs->mode_fixup(encoder, mode, > + adjusted_mode))) { > + DRM_DEBUG_KMS("Encoder fixup failed\n"); > + goto done; > + } > + } > + > + if (!(ret = crtc_funcs->mode_fixup(crtc, mode, adjusted_mode))) { > + DRM_DEBUG_KMS("CRTC fixup failed\n"); > + goto done; > + } > + DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); > + > + /* Prepare the encoders and CRTCs before setting the mode. */ > + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { > + > + if (encoder->crtc != crtc) > + continue; > + encoder_funcs = encoder->helper_private; > + /* Disable the encoders as the first thing we do. */ > + encoder_funcs->prepare(encoder); > + } > + > + intel_crtc_prepare_encoders(dev); > + > + crtc_funcs->prepare(crtc); > + > + /* Set up the DPLL and any encoders state that needs to adjust or depend > + * on the DPLL. > + */ > + ret = !crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb); > + if (!ret) > + goto done; > + > + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { > + > + if (encoder->crtc != crtc) > + continue; > + > + DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%d:%s]\n", > + encoder->base.id, drm_get_encoder_name(encoder), > + mode->base.id, mode->name); > + encoder_funcs = encoder->helper_private; > + encoder_funcs->mode_set(encoder, mode, adjusted_mode); > + } > + > + /* Now enable the clocks, plane, pipe, and connectors that we set up. */ > + crtc_funcs->commit(crtc); > + > + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { > + > + if (encoder->crtc != crtc) > + continue; > + > + encoder_funcs = encoder->helper_private; > + encoder_funcs->commit(encoder); > + > + } > + > + /* Store real post-adjustment hardware mode. */ > + crtc->hwmode = *adjusted_mode; > + > + /* Calculate and store various constants which > + * are later needed by vblank and swap-completion > + * timestamping. They are derived from true hwmode. > + */ > + drm_calc_timestamping_constants(crtc); > + > + /* FIXME: add subpixel order */ > +done: > + drm_mode_destroy(dev, adjusted_mode); > + if (!ret) { > + crtc->hwmode = saved_hwmode; > + crtc->mode = saved_mode; > + crtc->x = saved_x; > + crtc->y = saved_y; > + } > + > + return ret; > +} > + > static int intel_crtc_set_config(struct drm_mode_set *set) > { > struct drm_device *dev; > @@ -6817,9 +6968,8 @@ static int intel_crtc_set_config(struct drm_mode_set *set) > drm_mode_debug_printmodeline(set->mode); > old_fb = set->crtc->fb; > set->crtc->fb = set->fb; > - if (!drm_crtc_helper_set_mode(set->crtc, set->mode, > - set->x, set->y, > - old_fb)) { > + if (!intel_set_mode(set->crtc, set->mode, > + set->x, set->y, old_fb)) { > DRM_ERROR("failed to set mode on [CRTC:%d]\n", > set->crtc->base.id); > set->crtc->fb = old_fb; > @@ -6873,8 +7023,8 @@ fail: > > /* Try to restore the config */ > if (mode_changed && > - !drm_crtc_helper_set_mode(save_set.crtc, save_set.mode, save_set.x, > - save_set.y, save_set.fb)) > + !intel_set_mode(save_set.crtc, save_set.mode, > + save_set.x, save_set.y, save_set.fb)) > DRM_ERROR("failed to restore config after modeset failure\n"); > > kfree(save_connectors); > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > index 7ee954c..2abaaf6 100644 > --- a/drivers/gpu/drm/i915/intel_dp.c > +++ b/drivers/gpu/drm/i915/intel_dp.c > @@ -2312,9 +2312,8 @@ intel_dp_set_property(struct drm_connector *connector, > done: > if (intel_dp->base.base.crtc) { > struct drm_crtc *crtc = intel_dp->base.base.crtc; > - drm_crtc_helper_set_mode(crtc, &crtc->mode, > - crtc->x, crtc->y, > - crtc->fb); > + intel_set_mode(crtc, &crtc->mode, > + crtc->x, crtc->y, crtc->fb); > } > > return 0; > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > index e59cac3..c28fada 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -410,6 +410,8 @@ extern void intel_panel_disable_backlight(struct drm_device *dev); > extern void intel_panel_destroy_backlight(struct drm_device *dev); > extern enum drm_connector_status intel_panel_detect(struct drm_device *dev); > > +extern bool intel_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, > + int x, int y, struct drm_framebuffer *old_fb); > extern void intel_crtc_load_lut(struct drm_crtc *crtc); > extern void intel_crtc_update_dpms(struct drm_crtc *crtc); > extern void intel_encoder_noop(struct drm_encoder *encoder); > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c > index acddaaa..ef84097 100644 > --- a/drivers/gpu/drm/i915/intel_hdmi.c > +++ b/drivers/gpu/drm/i915/intel_hdmi.c > @@ -869,9 +869,8 @@ intel_hdmi_set_property(struct drm_connector *connector, > done: > if (intel_hdmi->base.base.crtc) { > struct drm_crtc *crtc = intel_hdmi->base.base.crtc; > - drm_crtc_helper_set_mode(crtc, &crtc->mode, > - crtc->x, crtc->y, > - crtc->fb); > + intel_set_mode(crtc, &crtc->mode, > + crtc->x, crtc->y, crtc->fb); > } > > return 0; > diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c > index 3baa224..fad82b2 100644 > --- a/drivers/gpu/drm/i915/intel_lvds.c > +++ b/drivers/gpu/drm/i915/intel_lvds.c > @@ -560,8 +560,8 @@ static int intel_lvds_set_property(struct drm_connector *connector, > * If the CRTC is enabled, the display will be changed > * according to the new panel fitting mode. > */ > - drm_crtc_helper_set_mode(crtc, &crtc->mode, > - crtc->x, crtc->y, crtc->fb); > + intel_set_mode(crtc, &crtc->mode, > + crtc->x, crtc->y, crtc->fb); > } > } > > diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c > index a01c470..88fb30d 100644 > --- a/drivers/gpu/drm/i915/intel_sdvo.c > +++ b/drivers/gpu/drm/i915/intel_sdvo.c > @@ -1879,8 +1879,8 @@ set_value: > done: > if (intel_sdvo->base.base.crtc) { > struct drm_crtc *crtc = intel_sdvo->base.base.crtc; > - drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, > - crtc->y, crtc->fb); > + intel_set_mode(crtc, &crtc->mode, > + crtc->x, crtc->y, crtc->fb); > } > > return 0; > diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c > index 281e0cf..16cb114 100644 > --- a/drivers/gpu/drm/i915/intel_tv.c > +++ b/drivers/gpu/drm/i915/intel_tv.c > @@ -1471,8 +1471,8 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop > } > > if (changed && crtc) > - drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, > - crtc->y, crtc->fb); > + intel_set_mode(crtc, &crtc->mode, > + crtc->x, crtc->y, crtc->fb); > out: > return ret; > } Acked-by: Jesse Barnes <jbarnes at virtuousgeek.org> -- Jesse Barnes, Intel Open Source Technology Center