diff mbox

drm/docs: more leftovers from the big vtable documentation pile

Message ID 1450286305-8980-1-git-send-email-daniel.vetter@ffwll.ch (mailing list archive)
State New, archived
Headers show

Commit Message

Daniel Vetter Dec. 16, 2015, 5:18 p.m. UTC
Another pile of vfuncs from the old gpu.tmpl xml documentation that
I've forgotten to delete. I spotted a few more things to
clarify/extend in the new kerneldoc while going through this once
more.

Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Thierry Reding <treding@nvidia.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 Documentation/DocBook/gpu.tmpl           | 188 -------------------------------
 include/drm/drm_modeset_helper_vtables.h |  28 ++++-
 2 files changed, 25 insertions(+), 191 deletions(-)

Comments

Thierry Reding Dec. 28, 2015, 10:22 a.m. UTC | #1
On Wed, Dec 16, 2015 at 06:18:25PM +0100, Daniel Vetter wrote:
> Another pile of vfuncs from the old gpu.tmpl xml documentation that
> I've forgotten to delete. I spotted a few more things to
> clarify/extend in the new kerneldoc while going through this once
> more.
> 
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Cc: Thierry Reding <treding@nvidia.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  Documentation/DocBook/gpu.tmpl           | 188 -------------------------------
>  include/drm/drm_modeset_helper_vtables.h |  28 ++++-
>  2 files changed, 25 insertions(+), 191 deletions(-)
> 
> diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl
> index a3764291c826..c0fa21c797fe 100644
> --- a/Documentation/DocBook/gpu.tmpl
> +++ b/Documentation/DocBook/gpu.tmpl
> @@ -1579,194 +1579,6 @@ void intel_crt_init(struct drm_device *dev)
>        entities.
>      </para>
>      <sect2>
> -      <title>Legacy CRTC Helper Operations</title>
> -      <itemizedlist>
> -        <listitem id="drm-helper-crtc-mode-fixup">
> -          <synopsis>bool (*mode_fixup)(struct drm_crtc *crtc,
> -                       const struct drm_display_mode *mode,
> -                       struct drm_display_mode *adjusted_mode);</synopsis>
> -          <para>
> -            Let CRTCs adjust the requested mode or reject it completely. This
> -            operation returns true if the mode is accepted (possibly after being
> -            adjusted) or false if it is rejected.
> -          </para>
> -          <para>
> -            The <methodname>mode_fixup</methodname> operation should reject the
> -            mode if it can't reasonably use it. The definition of "reasonable"
> -            is currently fuzzy in this context. One possible behaviour would be
> -            to set the adjusted mode to the panel timings when a fixed-mode
> -            panel is used with hardware capable of scaling. Another behaviour
> -            would be to accept any input mode and adjust it to the closest mode
> -            supported by the hardware (FIXME: This needs to be clarified).
> -          </para>
> -        </listitem>

I just noticed that this deviates somewhat from what is now in the new
documentation in include/drm/drm_modeset_helper_vtables.h. The new
documentation suggests that ->mode_fixup() should not modify
adjusted_mode but instead reject the mode if the conversion from mode to
adjusted_mode can't be supported. The new definition sounds much saner
to me, because if we allowed the CRTC's ->mode_fixup() to modify the
adjusted_mode, we'd need to make sure that the encoder (and bridge)
still accept it. And we'd need to potentially reiterate until everybody
agrees.

> diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
> index 29e0dc50031d..b995d5ec50a0 100644
> --- a/include/drm/drm_modeset_helper_vtables.h
> +++ b/include/drm/drm_modeset_helper_vtables.h
> @@ -131,6 +131,12 @@ struct drm_crtc_helper_funcs {
>  	 * Atomic drivers which need to inspect and adjust more state should
>  	 * instead use the @atomic_check callback.
>  	 *
> +	 * Also beware that the core nor helpers filters mode before passing the

"... neither the core nor the helpers filter modes before passing them ..."?

> +	 * to the driver. More specifically modes rejected by the ->mode_valid
> +	 * callback from #drm_connector_helper_funcs can still be requested by
> +	 * userspace and therefore also need to be rejected in either this hook,
> +	 * or the one in #drm_encoder_helper_funcs.

Hmm... that's odd. Why would one want to allow a mode that the connector
can't support? Also looking at drm_helper_probe_single_connector_modes()
this isn't quite true. That helper is used by all connectors except
vmwgfx. It also calls drm_mode_prune_invalid(), which will remove all
modes from the connector's mode list that don't have status == MODE_OK.
As far as I can see after they've been removed from the connector's mode
list they will no longer be exposed to userspace.

> +	 *
>  	 * RETURNS:
>  	 *
>  	 * True if an acceptable configuration is possible, false if the modeset
> @@ -188,7 +194,9 @@ struct drm_crtc_helper_funcs {
>  	 * This callback is used by the legacy CRTC helpers to set a new
>  	 * framebuffer and scanout position. It is optional and used as an
>  	 * optimized fast-path instead of a full mode set operation with all the
> -	 * resulting flickering. Since it can't update other planes it's
> +	 * resulting flickering. If it is not present
> +	 * drm_crtc_helper_set_config() will fall back to a full modeset, using
> +	 * the ->mode_set() callbac. Since it can't update other planes it's

"callback"

>  	 * incompatible with atomic modeset support.
>  	 *
>  	 * This callback is only used by the CRTC helpers and deprecated.
> @@ -439,6 +447,12 @@ struct drm_encoder_helper_funcs {
>  	 * Atomic drivers which need to inspect and adjust more state should
>  	 * instead use the @atomic_check callback.
>  	 *
> +	 * Also beware that the core nor helpers filters mode before passing the
> +	 * to the driver. More specifically modes rejected by the ->mode_valid
> +	 * callback from #drm_connector_helper_funcs can still be requested by
> +	 * userspace and therefore also need to be rejected in either this hook,
> +	 * or the one in #drm_crtc_helper_funcs.

Same comments as for struct drm_crtc_helper_funcs.

> +	 *
>  	 * RETURNS:
>  	 *
>  	 * True if an acceptable configuration is possible, false if the modeset
> @@ -640,8 +654,16 @@ struct drm_connector_helper_funcs {
>  	 * In this function drivers then parse the modes in the EDID and add
>  	 * them by calling drm_add_edid_modes(). But connectors that driver a
>  	 * fixed panel can also manually add specific modes using
> -	 * drm_mode_probed_add(). Finally drivers that support audio probably
> -	 * want to update the ELD data, too, using drm_edid_to_eld().
> +	 * drm_mode_probed_add(). Drivers who manually add modes should also

"drivers which" or "drivers that", I think.

> +	 * make sure that the @display_info, @width_mm and @height_mm fields of the
> +	 * struct #drm_connector are filled out.

I think "filled in" is slightly more appropriate in this case.

> +	 *
> +	 * Virtual drivers who just want some standard VESA mode with a given

"drivers which" or "drivers that".

Thierry
Daniel Vetter Jan. 4, 2016, 6:49 a.m. UTC | #2
On Mon, Dec 28, 2015 at 11:22:52AM +0100, Thierry Reding wrote:
> On Wed, Dec 16, 2015 at 06:18:25PM +0100, Daniel Vetter wrote:
> > Another pile of vfuncs from the old gpu.tmpl xml documentation that
> > I've forgotten to delete. I spotted a few more things to
> > clarify/extend in the new kerneldoc while going through this once
> > more.
> > 
> > Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > Cc: Thierry Reding <treding@nvidia.com>
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > ---
> >  Documentation/DocBook/gpu.tmpl           | 188 -------------------------------
> >  include/drm/drm_modeset_helper_vtables.h |  28 ++++-
> >  2 files changed, 25 insertions(+), 191 deletions(-)
> > 
> > diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl
> > index a3764291c826..c0fa21c797fe 100644
> > --- a/Documentation/DocBook/gpu.tmpl
> > +++ b/Documentation/DocBook/gpu.tmpl
> > @@ -1579,194 +1579,6 @@ void intel_crt_init(struct drm_device *dev)
> >        entities.
> >      </para>
> >      <sect2>
> > -      <title>Legacy CRTC Helper Operations</title>
> > -      <itemizedlist>
> > -        <listitem id="drm-helper-crtc-mode-fixup">
> > -          <synopsis>bool (*mode_fixup)(struct drm_crtc *crtc,
> > -                       const struct drm_display_mode *mode,
> > -                       struct drm_display_mode *adjusted_mode);</synopsis>
> > -          <para>
> > -            Let CRTCs adjust the requested mode or reject it completely. This
> > -            operation returns true if the mode is accepted (possibly after being
> > -            adjusted) or false if it is rejected.
> > -          </para>
> > -          <para>
> > -            The <methodname>mode_fixup</methodname> operation should reject the
> > -            mode if it can't reasonably use it. The definition of "reasonable"
> > -            is currently fuzzy in this context. One possible behaviour would be
> > -            to set the adjusted mode to the panel timings when a fixed-mode
> > -            panel is used with hardware capable of scaling. Another behaviour
> > -            would be to accept any input mode and adjust it to the closest mode
> > -            supported by the hardware (FIXME: This needs to be clarified).
> > -          </para>
> > -        </listitem>
> 
> I just noticed that this deviates somewhat from what is now in the new
> documentation in include/drm/drm_modeset_helper_vtables.h. The new
> documentation suggests that ->mode_fixup() should not modify
> adjusted_mode but instead reject the mode if the conversion from mode to
> adjusted_mode can't be supported. The new definition sounds much saner
> to me, because if we allowed the CRTC's ->mode_fixup() to modify the
> adjusted_mode, we'd need to make sure that the encoder (and bridge)
> still accept it. And we'd need to potentially reiterate until everybody
> agrees.

Yeah, I simply addressed the FIXME while typing the new docs and made this
a strong recommendation (that's why I picked "should" instead of "must").
There's some drivers (at least i915's TV-out) where the input mode is
massively mangled, but no one will ever fix this.

> > diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
> > index 29e0dc50031d..b995d5ec50a0 100644
> > --- a/include/drm/drm_modeset_helper_vtables.h
> > +++ b/include/drm/drm_modeset_helper_vtables.h
> > @@ -131,6 +131,12 @@ struct drm_crtc_helper_funcs {
> >  	 * Atomic drivers which need to inspect and adjust more state should
> >  	 * instead use the @atomic_check callback.
> >  	 *
> > +	 * Also beware that the core nor helpers filters mode before passing the
> 
> "... neither the core nor the helpers filter modes before passing them ..."?
> 
> > +	 * to the driver. More specifically modes rejected by the ->mode_valid
> > +	 * callback from #drm_connector_helper_funcs can still be requested by
> > +	 * userspace and therefore also need to be rejected in either this hook,
> > +	 * or the one in #drm_encoder_helper_funcs.
> 
> Hmm... that's odd. Why would one want to allow a mode that the connector
> can't support? Also looking at drm_helper_probe_single_connector_modes()
> this isn't quite true. That helper is used by all connectors except
> vmwgfx. It also calls drm_mode_prune_invalid(), which will remove all
> modes from the connector's mode list that don't have status == MODE_OK.
> As far as I can see after they've been removed from the connector's mode
> list they will no longer be exposed to userspace.

Maybe I need to hammer this in more, but it's a common misconception that
userspace can only ask for modes in the connector list. Generally that's
what's happening, but there's not restrictions on userspace to ask for a
mode which is _not_ in the connector's mode list.

If you don't believe that, look at xrandr --addmode and try yourself.

That's why drivers MUST filter modes in both mode_valid and mode_fixup.
Any suggestions for how to make this even more clear?

Aside, I tried looking into untangling this a bit with a helper to
implement mode_valid in terms of mode_fixup (by just passing a dummy
adjusted_mode in). But figuring out which encoder/crtc to take (in
general) stopped that idea. Maybe we just need to iterate over all
possible configurations. The other problem was that mode_fixup was allowed
to change software state in legacy drivers, but atomic fixed that.

I'll apply all the other comments.

Thanks, Daniel
Thierry Reding Jan. 5, 2016, 3:11 p.m. UTC | #3
On Mon, Jan 04, 2016 at 07:49:41AM +0100, Daniel Vetter wrote:
> On Mon, Dec 28, 2015 at 11:22:52AM +0100, Thierry Reding wrote:
> > On Wed, Dec 16, 2015 at 06:18:25PM +0100, Daniel Vetter wrote:
> > > Another pile of vfuncs from the old gpu.tmpl xml documentation that
> > > I've forgotten to delete. I spotted a few more things to
> > > clarify/extend in the new kerneldoc while going through this once
> > > more.
> > > 
> > > Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > > Cc: Thierry Reding <treding@nvidia.com>
> > > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > > ---
> > >  Documentation/DocBook/gpu.tmpl           | 188 -------------------------------
> > >  include/drm/drm_modeset_helper_vtables.h |  28 ++++-
> > >  2 files changed, 25 insertions(+), 191 deletions(-)
> > > 
> > > diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl
> > > index a3764291c826..c0fa21c797fe 100644
> > > --- a/Documentation/DocBook/gpu.tmpl
> > > +++ b/Documentation/DocBook/gpu.tmpl
> > > @@ -1579,194 +1579,6 @@ void intel_crt_init(struct drm_device *dev)
> > >        entities.
> > >      </para>
> > >      <sect2>
> > > -      <title>Legacy CRTC Helper Operations</title>
> > > -      <itemizedlist>
> > > -        <listitem id="drm-helper-crtc-mode-fixup">
> > > -          <synopsis>bool (*mode_fixup)(struct drm_crtc *crtc,
> > > -                       const struct drm_display_mode *mode,
> > > -                       struct drm_display_mode *adjusted_mode);</synopsis>
> > > -          <para>
> > > -            Let CRTCs adjust the requested mode or reject it completely. This
> > > -            operation returns true if the mode is accepted (possibly after being
> > > -            adjusted) or false if it is rejected.
> > > -          </para>
> > > -          <para>
> > > -            The <methodname>mode_fixup</methodname> operation should reject the
> > > -            mode if it can't reasonably use it. The definition of "reasonable"
> > > -            is currently fuzzy in this context. One possible behaviour would be
> > > -            to set the adjusted mode to the panel timings when a fixed-mode
> > > -            panel is used with hardware capable of scaling. Another behaviour
> > > -            would be to accept any input mode and adjust it to the closest mode
> > > -            supported by the hardware (FIXME: This needs to be clarified).
> > > -          </para>
> > > -        </listitem>
> > 
> > I just noticed that this deviates somewhat from what is now in the new
> > documentation in include/drm/drm_modeset_helper_vtables.h. The new
> > documentation suggests that ->mode_fixup() should not modify
> > adjusted_mode but instead reject the mode if the conversion from mode to
> > adjusted_mode can't be supported. The new definition sounds much saner
> > to me, because if we allowed the CRTC's ->mode_fixup() to modify the
> > adjusted_mode, we'd need to make sure that the encoder (and bridge)
> > still accept it. And we'd need to potentially reiterate until everybody
> > agrees.
> 
> Yeah, I simply addressed the FIXME while typing the new docs and made this
> a strong recommendation (that's why I picked "should" instead of "must").
> There's some drivers (at least i915's TV-out) where the input mode is
> massively mangled, but no one will ever fix this.

Okay, fine with me.

> > > diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
> > > index 29e0dc50031d..b995d5ec50a0 100644
> > > --- a/include/drm/drm_modeset_helper_vtables.h
> > > +++ b/include/drm/drm_modeset_helper_vtables.h
> > > @@ -131,6 +131,12 @@ struct drm_crtc_helper_funcs {
> > >  	 * Atomic drivers which need to inspect and adjust more state should
> > >  	 * instead use the @atomic_check callback.
> > >  	 *
> > > +	 * Also beware that the core nor helpers filters mode before passing the
> > 
> > "... neither the core nor the helpers filter modes before passing them ..."?
> > 
> > > +	 * to the driver. More specifically modes rejected by the ->mode_valid
> > > +	 * callback from #drm_connector_helper_funcs can still be requested by
> > > +	 * userspace and therefore also need to be rejected in either this hook,
> > > +	 * or the one in #drm_encoder_helper_funcs.
> > 
> > Hmm... that's odd. Why would one want to allow a mode that the connector
> > can't support? Also looking at drm_helper_probe_single_connector_modes()
> > this isn't quite true. That helper is used by all connectors except
> > vmwgfx. It also calls drm_mode_prune_invalid(), which will remove all
> > modes from the connector's mode list that don't have status == MODE_OK.
> > As far as I can see after they've been removed from the connector's mode
> > list they will no longer be exposed to userspace.
> 
> Maybe I need to hammer this in more, but it's a common misconception that
> userspace can only ask for modes in the connector list. Generally that's
> what's happening, but there's not restrictions on userspace to ask for a
> mode which is _not_ in the connector's mode list.
> 
> If you don't believe that, look at xrandr --addmode and try yourself.
> 
> That's why drivers MUST filter modes in both mode_valid and mode_fixup.
> Any suggestions for how to make this even more clear?

Currently that's not very explicit in the text, since it only suggests
that modes aren't filtered out. It doesn't say anything about the
possibility of modes being manually added by userspace. How about
something along these lines:

    While the list of modes that is advertised to userspace is filtered
    using the connector's ->mode_valid() callback, neither the core nor
    the helpers do any filtering on modes passed in from userspace when
    setting a mode. It is therefore possible for userspace to pass in a
    mode that was previously filtered out using ->mode_valid() or add a
    custom mode that wasn't probed from EDID or similar to begin with.
    Even though this is an advanced feature and rarely used nowadays,
    some users rely on being able to specify modes manually so drivers
    must be prepared to deal with it. Specifically this means that all
    drivers need not only validate modes in ->mode_valid() but also in
    ->mode_fixup() to make sure invalid modes passed in from userspace
    are rejected.

> Aside, I tried looking into untangling this a bit with a helper to
> implement mode_valid in terms of mode_fixup (by just passing a dummy
> adjusted_mode in). But figuring out which encoder/crtc to take (in
> general) stopped that idea. Maybe we just need to iterate over all
> possible configurations. The other problem was that mode_fixup was allowed
> to change software state in legacy drivers, but atomic fixed that.

Yeah, it sounds fine to me to keep this as-is, as long as everybody is
clear on how it works.

Thierry
diff mbox

Patch

diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl
index a3764291c826..c0fa21c797fe 100644
--- a/Documentation/DocBook/gpu.tmpl
+++ b/Documentation/DocBook/gpu.tmpl
@@ -1579,194 +1579,6 @@  void intel_crt_init(struct drm_device *dev)
       entities.
     </para>
     <sect2>
-      <title>Legacy CRTC Helper Operations</title>
-      <itemizedlist>
-        <listitem id="drm-helper-crtc-mode-fixup">
-          <synopsis>bool (*mode_fixup)(struct drm_crtc *crtc,
-                       const struct drm_display_mode *mode,
-                       struct drm_display_mode *adjusted_mode);</synopsis>
-          <para>
-            Let CRTCs adjust the requested mode or reject it completely. This
-            operation returns true if the mode is accepted (possibly after being
-            adjusted) or false if it is rejected.
-          </para>
-          <para>
-            The <methodname>mode_fixup</methodname> operation should reject the
-            mode if it can't reasonably use it. The definition of "reasonable"
-            is currently fuzzy in this context. One possible behaviour would be
-            to set the adjusted mode to the panel timings when a fixed-mode
-            panel is used with hardware capable of scaling. Another behaviour
-            would be to accept any input mode and adjust it to the closest mode
-            supported by the hardware (FIXME: This needs to be clarified).
-          </para>
-        </listitem>
-        <listitem>
-          <synopsis>int (*mode_set_base)(struct drm_crtc *crtc, int x, int y,
-                     struct drm_framebuffer *old_fb)</synopsis>
-          <para>
-            Move the CRTC on the current frame buffer (stored in
-            <literal>crtc-&gt;fb</literal>) to position (x,y). Any of the frame
-            buffer, x position or y position may have been modified.
-          </para>
-          <para>
-            This helper operation is optional. If not provided, the
-            <function>drm_crtc_helper_set_config</function> function will fall
-            back to the <methodname>mode_set</methodname> helper operation.
-          </para>
-          <note><para>
-            FIXME: Why are x and y passed as arguments, as they can be accessed
-            through <literal>crtc-&gt;x</literal> and
-            <literal>crtc-&gt;y</literal>?
-          </para></note>
-        </listitem>
-        <listitem>
-          <synopsis>void (*prepare)(struct drm_crtc *crtc);</synopsis>
-          <para>
-            Prepare the CRTC for mode setting. This operation is called after
-            validating the requested mode. Drivers use it to perform
-            device-specific operations required before setting the new mode.
-          </para>
-        </listitem>
-        <listitem>
-          <synopsis>int (*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);</synopsis>
-          <para>
-            Set a new mode, position and frame buffer. Depending on the device
-            requirements, the mode can be stored internally by the driver and
-            applied in the <methodname>commit</methodname> operation, or
-            programmed to the hardware immediately.
-          </para>
-          <para>
-            The <methodname>mode_set</methodname> operation returns 0 on success
-	    or a negative error code if an error occurs.
-          </para>
-        </listitem>
-        <listitem>
-          <synopsis>void (*commit)(struct drm_crtc *crtc);</synopsis>
-          <para>
-            Commit a mode. This operation is called after setting the new mode.
-            Upon return the device must use the new mode and be fully
-            operational.
-          </para>
-        </listitem>
-      </itemizedlist>
-    </sect2>
-    <sect2>
-      <title>Encoder Helper Operations</title>
-      <itemizedlist>
-        <listitem>
-          <synopsis>bool (*mode_fixup)(struct drm_encoder *encoder,
-                       const struct drm_display_mode *mode,
-                       struct drm_display_mode *adjusted_mode);</synopsis>
-          <para>
-            Let encoders adjust the requested mode or reject it completely. This
-            operation returns true if the mode is accepted (possibly after being
-            adjusted) or false if it is rejected. See the
-            <link linkend="drm-helper-crtc-mode-fixup">mode_fixup CRTC helper
-            operation</link> for an explanation of the allowed adjustments.
-          </para>
-        </listitem>
-        <listitem>
-          <synopsis>void (*prepare)(struct drm_encoder *encoder);</synopsis>
-          <para>
-            Prepare the encoder for mode setting. This operation is called after
-            validating the requested mode. Drivers use it to perform
-            device-specific operations required before setting the new mode.
-          </para>
-        </listitem>
-        <listitem>
-          <synopsis>void (*mode_set)(struct drm_encoder *encoder,
-                 struct drm_display_mode *mode,
-                 struct drm_display_mode *adjusted_mode);</synopsis>
-          <para>
-            Set a new mode. Depending on the device requirements, the mode can
-            be stored internally by the driver and applied in the
-            <methodname>commit</methodname> operation, or programmed to the
-            hardware immediately.
-          </para>
-        </listitem>
-        <listitem>
-          <synopsis>void (*commit)(struct drm_encoder *encoder);</synopsis>
-          <para>
-            Commit a mode. This operation is called after setting the new mode.
-            Upon return the device must use the new mode and be fully
-            operational.
-          </para>
-        </listitem>
-      </itemizedlist>
-    </sect2>
-    <sect2>
-      <title>Connector Helper Operations</title>
-      <itemizedlist>
-        <listitem>
-          <synopsis>struct drm_encoder *(*best_encoder)(struct drm_connector *connector);</synopsis>
-          <para>
-            Return a pointer to the best encoder for the connecter. Device that
-            map connectors to encoders 1:1 simply return the pointer to the
-            associated encoder. This operation is mandatory.
-          </para>
-        </listitem>
-        <listitem>
-          <synopsis>int (*get_modes)(struct drm_connector *connector);</synopsis>
-          <para>
-            Fill the connector's <structfield>probed_modes</structfield> list
-            by parsing EDID data with <function>drm_add_edid_modes</function>,
-            adding standard VESA DMT modes with <function>drm_add_modes_noedid</function>,
-            or calling <function>drm_mode_probed_add</function> directly for every
-            supported mode and return the number of modes it has detected. This
-            operation is mandatory.
-          </para>
-          <para>
-            Note that the caller function will automatically add standard VESA
-            DMT modes up to 1024x768 if the <methodname>get_modes</methodname>
-            helper operation returns no mode and if the connector status is
-            connector_status_connected. There is no need to call
-            <function>drm_add_edid_modes</function> manually in that case.
-          </para>
-          <para>
-            The <structfield>vrefresh</structfield> value is computed by
-            <function>drm_helper_probe_single_connector_modes</function>.
-          </para>
-          <para>
-            When parsing EDID data, <function>drm_add_edid_modes</function> fills the
-            connector <structfield>display_info</structfield>
-            <structfield>width_mm</structfield> and
-            <structfield>height_mm</structfield> fields. When creating modes
-            manually the <methodname>get_modes</methodname> helper operation must
-            set the <structfield>display_info</structfield>
-            <structfield>width_mm</structfield> and
-            <structfield>height_mm</structfield> fields if they haven't been set
-            already (for instance at initialization time when a fixed-size panel is
-            attached to the connector). The mode <structfield>width_mm</structfield>
-            and <structfield>height_mm</structfield> fields are only used internally
-            during EDID parsing and should not be set when creating modes manually.
-          </para>
-        </listitem>
-        <listitem>
-          <synopsis>int (*mode_valid)(struct drm_connector *connector,
-		  struct drm_display_mode *mode);</synopsis>
-          <para>
-            Verify whether a mode is valid for the connector. Return MODE_OK for
-            supported modes and one of the enum drm_mode_status values (MODE_*)
-            for unsupported modes. This operation is optional.
-          </para>
-          <para>
-            As the mode rejection reason is currently not used beside for
-            immediately removing the unsupported mode, an implementation can
-            return MODE_BAD regardless of the exact reason why the mode is not
-            valid.
-          </para>
-          <note><para>
-            Note that the <methodname>mode_valid</methodname> helper operation is
-            only called for modes detected by the device, and
-            <emphasis>not</emphasis> for modes set by the user through the CRTC
-            <methodname>set_config</methodname> operation.
-          </para></note>
-        </listitem>
-      </itemizedlist>
-    </sect2>
-    <sect2>
       <title>Atomic Modeset Helper Functions Reference</title>
       <sect3>
 	<title>Overview</title>
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index 29e0dc50031d..b995d5ec50a0 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -131,6 +131,12 @@  struct drm_crtc_helper_funcs {
 	 * Atomic drivers which need to inspect and adjust more state should
 	 * instead use the @atomic_check callback.
 	 *
+	 * Also beware that the core nor helpers filters mode before passing the
+	 * to the driver. More specifically modes rejected by the ->mode_valid
+	 * callback from #drm_connector_helper_funcs can still be requested by
+	 * userspace and therefore also need to be rejected in either this hook,
+	 * or the one in #drm_encoder_helper_funcs.
+	 *
 	 * RETURNS:
 	 *
 	 * True if an acceptable configuration is possible, false if the modeset
@@ -188,7 +194,9 @@  struct drm_crtc_helper_funcs {
 	 * This callback is used by the legacy CRTC helpers to set a new
 	 * framebuffer and scanout position. It is optional and used as an
 	 * optimized fast-path instead of a full mode set operation with all the
-	 * resulting flickering. Since it can't update other planes it's
+	 * resulting flickering. If it is not present
+	 * drm_crtc_helper_set_config() will fall back to a full modeset, using
+	 * the ->mode_set() callbac. Since it can't update other planes it's
 	 * incompatible with atomic modeset support.
 	 *
 	 * This callback is only used by the CRTC helpers and deprecated.
@@ -439,6 +447,12 @@  struct drm_encoder_helper_funcs {
 	 * Atomic drivers which need to inspect and adjust more state should
 	 * instead use the @atomic_check callback.
 	 *
+	 * Also beware that the core nor helpers filters mode before passing the
+	 * to the driver. More specifically modes rejected by the ->mode_valid
+	 * callback from #drm_connector_helper_funcs can still be requested by
+	 * userspace and therefore also need to be rejected in either this hook,
+	 * or the one in #drm_crtc_helper_funcs.
+	 *
 	 * RETURNS:
 	 *
 	 * True if an acceptable configuration is possible, false if the modeset
@@ -640,8 +654,16 @@  struct drm_connector_helper_funcs {
 	 * In this function drivers then parse the modes in the EDID and add
 	 * them by calling drm_add_edid_modes(). But connectors that driver a
 	 * fixed panel can also manually add specific modes using
-	 * drm_mode_probed_add(). Finally drivers that support audio probably
-	 * want to update the ELD data, too, using drm_edid_to_eld().
+	 * drm_mode_probed_add(). Drivers who manually add modes should also
+	 * make sure that the @display_info, @width_mm and @height_mm fields of the
+	 * struct #drm_connector are filled out.
+	 *
+	 * Virtual drivers who just want some standard VESA mode with a given
+	 * resolution can call drm_add_modes_noedid(), and mark the preferred
+	 * one using drm_set_preferred_mode().
+	 *
+	 * Finally drivers that support audio probably want to update the ELD
+	 * data, too, using drm_edid_to_eld().
 	 *
 	 * This function is only called after the ->detect() hook has indicated
 	 * that a sink is connected and when the EDID isn't overridden through