On Sat, Oct 22, 2016 at 05:46:30PM +0300, Ville Syrjälä wrote: > On Sat, Oct 22, 2016 at 04:01:14PM +0200, Daniel Vetter wrote: > > On Sat, Oct 22, 2016 at 10:47:25AM +0200, Daniel Vetter wrote: > > > On Fri, Oct 21, 2016 at 04:45:39PM -0700, Manasi Navare wrote: > > > > This function provides a way for the driver to redo a > > > > modeset on the current mode and retry the link training > > > > at a lower link rate/lane count/bpp. This will get called > > > > incase the link training fails during the current modeset. > > > > > > > > Cc: dri-devel at lists.freedesktop.org > > > > Cc: Jani Nikula <jani.nikula at linux.intel.com> > > > > Cc: Daniel Vetter <daniel.vetter at intel.com> > > > > Cc: Ville Syrjala <ville.syrjala at linux.intel.com> > > > > Signed-off-by: Manasi Navare <manasi.d.navare at intel.com> > > > > --- > > > > drivers/gpu/drm/drm_atomic_helper.c | 58 > > > > +++++++++++++++++++++++++++++++++++++ > > > > include/drm/drm_atomic_helper.h | 1 + > > > > 2 files changed, 59 insertions(+) > > > > > > > > diff --git a/drivers/gpu/drm/drm_atomic_helper.c > > > > b/drivers/gpu/drm/drm_atomic_helper.c > > > > index f936276..0c1614e 100644 > > > > --- a/drivers/gpu/drm/drm_atomic_helper.c > > > > +++ b/drivers/gpu/drm/drm_atomic_helper.c > > > > @@ -2895,6 +2895,64 @@ int drm_atomic_helper_connector_dpms(struct > > > > drm_connector *connector, > > > > EXPORT_SYMBOL(drm_atomic_helper_connector_dpms); > > > > > > > > /** > > > > + * drm_atomic_helper_connector_modeset - Force a modeset on a connector > > > > + * @connector: DRM connector > > > > + * > > > > + * Provides a way to redo a modeset with the current mode so that it > > > > can > > > > + * drop the bpp, link rate/lane count and retry the link training. > > > > + * > > > > + * Returns: > > > > + * Returns 0 on success, negative errno numbers on failure. > > > > + */ > > > > +int > > > > +drm_atomic_helper_connector_modeset(struct drm_connector *connector) > > > > +{ > > > > + struct drm_device *dev = connector->dev; > > > > + struct drm_modeset_acquire_ctx ctx; > > > > + struct drm_atomic_state *state; > > > > + struct drm_connector_state *connector_state; > > > > + struct drm_crtc_state *crtc_state; > > > > + int ret = 0; > > > > + > > > > + drm_modeset_acquire_init(&ctx, 0); > > > > + state = drm_atomic_state_alloc(dev); > > > > + if (!state) { > > > > + ret = -ENOMEM; > > > > + goto fail; > > > > + } > > > > + state->acquire_ctx = &ctx; > > > > +retry: > > > > + ret = 0; > > > > + connector_state = drm_atomic_get_connector_state(state, > > > > connector); > > > > + if (IS_ERR(connector_state)) { > > > > + ret = PTR_ERR(connector_state); > > > > + goto fail; > > > > + } > > > > + if (!connector_state->crtc) > > > > + goto fail; > > > > + > > > > + crtc_state = drm_atomic_get_existing_crtc_state(state, > > > > + > > > > connector_state->crtc); > > > > + crtc_state->connectors_changed = true; > > > > > > This line here only works if the driver uses the helpers for checking and > > > commit, and when it doesn't overwrite connectors_changed. I think the > > > kerneldoc should mention this. > > > > > > The other issue: You cannot call this from modeset code itself because of > > > recursion. I think this also must be mentioned. > > > > And if this indeed does a modeset then we have again the same issue as > > with upfront link training when the pipe is supposed to be on: Userspace > > can observe the kernel playing tricks because the vblank support will be > > temporarily disabled. > > > > Not sure how to best fix this, but might be good to grab the crtc->mutex > > in the vblank code for stuff like this. > > We're going to have the same problem with async modeset as well.
Async modeset is ok because userspace expects that the pipe will go off/on, and the kernel will send out an event to signal when the pipe is guaranteed to be on and can be started to be used. It's random modesets afterwards I'm concerned about. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch