On Fri, May 22, 2015 at 01:34:52PM +0100, Daniel Stone wrote: > Add a new helper, to be used later for blob property management, that > sets the mode for a CRTC state, as well as updating the CRTC enable/active > state at the same time. > > Signed-off-by: Daniel Stone <daniels@xxxxxxxxxxxxx> > Tested-by: Sean Paul <seanpaul@xxxxxxxxxxxx> A few small nits below. -Daniel > --- > drivers/gpu/drm/drm_atomic.c | 42 ++++++++++++++++++++++++++++++++++++ > drivers/gpu/drm/drm_atomic_helper.c | 24 ++++++--------------- > drivers/gpu/drm/drm_crtc_helper.c | 6 +++--- > drivers/gpu/drm/i915/intel_display.c | 16 +++++++++----- > include/drm/drm_atomic.h | 6 ++++++ > 5 files changed, 68 insertions(+), 26 deletions(-) > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c > index 3134f50..67c251f 100644 > --- a/drivers/gpu/drm/drm_atomic.c > +++ b/drivers/gpu/drm/drm_atomic.c > @@ -290,6 +290,48 @@ drm_atomic_get_crtc_state(struct drm_atomic_state *state, > EXPORT_SYMBOL(drm_atomic_get_crtc_state); > > /** > + * drm_atomic_set_mode_for_crtc - set mode for CRTC > + * @state: the CRTC whose incoming state to update > + * @mode: kernel-internal mode to use for the CRTC, or NULL to disable > + * > + * Set a mode (originating from the kernel) on the desired CRTC state, and > + * update the CRTC state's enable and mode_changed parameters as necessary. > + * If disabling, it will also set active to false. Kerneldoc for return values is missing. Fairly important since many atomic functions can return -EDEADLK, but this one doesn (even not when all the patches are applied). > + */ > +int drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state, > + struct drm_display_mode *mode) > +{ > + /* Early return for no change. */ > + if (!mode && !state->enable) > + return 0; > + if (mode && state->enable && > + memcmp(&state->mode, mode, sizeof(*mode)) == 0) > + return 0; > + > + state->mode_changed = true; Layering violation: ->mode_changed is purely something for the benefit of drivers/helpers and not something the core manadates. Hence this should get removed imo. > + > + if (mode) { > + drm_mode_copy(&state->mode, mode); > + state->enable = true; > + } else { > + memset(&state->mode, 0, sizeof(state->mode)); > + state->enable = false; > + state->active = false; > + } > + > + if (state->enable) > + DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n", > + mode->name, state); > + else > + DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n", > + state); > + > + return 0; > +} > +EXPORT_SYMBOL(drm_atomic_set_mode_for_crtc); > + > + > +/** > * drm_atomic_crtc_set_property - set property on CRTC > * @crtc: the drm CRTC to set a property on > * @state: the state object to update with the new property value > diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c > index a64bacd..70ce243 100644 > --- a/drivers/gpu/drm/drm_atomic_helper.c > +++ b/drivers/gpu/drm/drm_atomic_helper.c > @@ -369,20 +369,6 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, > struct drm_connector_state *connector_state; > int i, ret; > > - for_each_crtc_in_state(state, crtc, crtc_state, i) { > - if (!drm_mode_equal(&crtc->state->mode, &crtc_state->mode)) { > - DRM_DEBUG_ATOMIC("[CRTC:%d] mode changed\n", > - crtc->base.id); > - crtc_state->mode_changed = true; > - } > - > - if (crtc->state->enable != crtc_state->enable) { > - DRM_DEBUG_ATOMIC("[CRTC:%d] enable changed\n", > - crtc->base.id); > - crtc_state->mode_changed = true; > - } > - } Ofc then this hunk here needs to stay. > - > for_each_connector_in_state(state, connector, connector_state, i) { > /* > * This only sets crtc->mode_changed for routing changes, > @@ -1607,8 +1593,9 @@ retry: > WARN_ON(set->fb); > WARN_ON(set->num_connectors); > > - crtc_state->enable = false; > - crtc_state->active = false; > + ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL); > + if (ret != 0) > + goto fail; > > ret = drm_atomic_set_crtc_for_plane(primary_state, NULL); > if (ret != 0) > @@ -1622,9 +1609,10 @@ retry: > WARN_ON(!set->fb); > WARN_ON(!set->num_connectors); > > - crtc_state->enable = true; > + ret = drm_atomic_set_mode_for_crtc(crtc_state, set->mode); > + if (ret != 0) > + goto fail; > crtc_state->active = true; > - drm_mode_copy(&crtc_state->mode, set->mode); > > ret = drm_atomic_set_crtc_for_plane(primary_state, crtc); > if (ret != 0) > diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c > index 9297a61..cc77a4f 100644 > --- a/drivers/gpu/drm/drm_crtc_helper.c > +++ b/drivers/gpu/drm/drm_crtc_helper.c > @@ -937,10 +937,10 @@ int drm_helper_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mod > crtc_state->crtc = crtc; > } > > - crtc_state->enable = true; > crtc_state->planes_changed = true; > - crtc_state->mode_changed = true; > - drm_mode_copy(&crtc_state->mode, mode); > + ret = drm_atomic_set_mode_for_crtc(crtc_state, mode); > + if (ret) > + goto out; > drm_mode_copy(&crtc_state->adjusted_mode, adjusted_mode); > > if (crtc_funcs->atomic_check) { > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > index 240092a..7e31972 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -9896,7 +9896,9 @@ retry: > if (ret) > goto fail; > > - drm_mode_copy(&crtc_state->base.mode, mode); > + ret = drm_atomic_set_mode_for_crtc(&crtc_state->base, mode); > + if (ret) > + goto fail; > > if (intel_set_mode(crtc, state)) { > DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n"); > @@ -12494,8 +12496,11 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc) > > crtc_state->base.enable = intel_crtc->new_enabled; > > - if (&intel_crtc->base == crtc) > - drm_mode_copy(&crtc_state->base.mode, &crtc->mode); > + if (&intel_crtc->base == crtc) { > + ret = drm_atomic_set_mode_for_crtc(&crtc_state->base, > + &crtc->mode); > + WARN_ON(ret); > + } > } > > intel_modeset_setup_plane_state(state, crtc, &crtc->mode, > @@ -12633,8 +12638,9 @@ intel_modeset_stage_output_state(struct drm_device *dev, > if (IS_ERR(crtc_state)) > return PTR_ERR(crtc_state); > > - if (set->mode) > - drm_mode_copy(&crtc_state->mode, set->mode); > + ret = drm_atomic_set_mode_for_crtc(crtc_state, set->mode); > + if (ret) > + return ret; > > if (set->num_connectors) > crtc_state->active = true; > diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h > index e89db0c..55f4604 100644 > --- a/include/drm/drm_atomic.h > +++ b/include/drm/drm_atomic.h > @@ -110,6 +110,12 @@ drm_atomic_get_existing_connector_state(struct drm_atomic_state *state, > } > > int __must_check > +drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state, > + struct drm_display_mode *mode); > +int __must_check > +drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state, > + struct drm_property_blob *blob); > +int __must_check > drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state, > struct drm_crtc *crtc); > void drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state, > -- > 2.4.1 > > _______________________________________________ > dri-devel mailing list > dri-devel@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/dri-devel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel