Message ID | 20160831160913.12991-3-daniel.vetter@ffwll.ch (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 8/31/2016 9:39 PM, Daniel Vetter wrote: > We don't want to burry the bridge structures kerneldoc in drm_crtc.h. > > Cc: Archit Taneja <archit.taneja@gmail.com> Reviewed-by: Archit Taneja <architt@codeaurora.org> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> > --- > Documentation/gpu/drm-kms-helpers.rst | 7 ++ > drivers/gpu/drm/drm_bridge.c | 5 +- > include/drm/drm_bridge.h | 218 ++++++++++++++++++++++++++++++++++ > include/drm/drm_connector.h | 4 + > include/drm/drm_crtc.h | 187 +---------------------------- > include/drm/drm_mode_object.h | 1 + > include/drm/drm_modes.h | 4 + > 7 files changed, 237 insertions(+), 189 deletions(-) > create mode 100644 include/drm/drm_bridge.h > > diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst > index 59fa3c11efab..48fc5a96bf95 100644 > --- a/Documentation/gpu/drm-kms-helpers.rst > +++ b/Documentation/gpu/drm-kms-helpers.rst > @@ -126,6 +126,13 @@ Default bridge callback sequence > .. kernel-doc:: drivers/gpu/drm/drm_bridge.c > :doc: bridge callbacks > > + > +Bridge Helper Reference > +------------------------- > + > +.. kernel-doc:: include/drm/drm_bridge.h > + :internal: > + > .. kernel-doc:: drivers/gpu/drm/drm_bridge.c > :export: > > diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c > index 484046664d6c..0ee052b7c21a 100644 > --- a/drivers/gpu/drm/drm_bridge.c > +++ b/drivers/gpu/drm/drm_bridge.c > @@ -23,10 +23,9 @@ > > #include <linux/err.h> > #include <linux/module.h> > +#include <linux/mutex.h> > > -#include <drm/drm_crtc.h> > - > -#include "drm/drmP.h" > +#include <drm/drm_bridge.h> > > /** > * DOC: overview > diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h > new file mode 100644 > index 000000000000..530a1d6e8cde > --- /dev/null > +++ b/include/drm/drm_bridge.h > @@ -0,0 +1,218 @@ > +/* > + * Copyright (c) 2016 Intel Corporation > + * > + * Permission to use, copy, modify, distribute, and sell this software and its > + * documentation for any purpose is hereby granted without fee, provided that > + * the above copyright notice appear in all copies and that both that copyright > + * notice and this permission notice appear in supporting documentation, and > + * that the name of the copyright holders not be used in advertising or > + * publicity pertaining to distribution of the software without specific, > + * written prior permission. The copyright holders make no representations > + * about the suitability of this software for any purpose. It is provided "as > + * is" without express or implied warranty. > + * > + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, > + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO > + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR > + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, > + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER > + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE > + * OF THIS SOFTWARE. > + */ > + > +#ifndef __DRM_BRIDGE_H__ > +#define __DRM_BRIDGE_H__ > + > +#include <linux/list.h> > +#include <linux/ctype.h> > +#include <drm/drm_mode_object.h> > +#include <drm/drm_modes.h> > + > +struct drm_bridge; > + > +/** > + * struct drm_bridge_funcs - drm_bridge control functions > + */ > +struct drm_bridge_funcs { > + /** > + * @attach: > + * > + * This callback is invoked whenever our bridge is being attached to a > + * &drm_encoder. > + * > + * The attach callback is optional. > + * > + * RETURNS: > + * > + * Zero on success, error code on failure. > + */ > + int (*attach)(struct drm_bridge *bridge); > + > + /** > + * @detach: > + * > + * This callback is invoked whenever our bridge is being detached from a > + * &drm_encoder. > + * > + * The detach callback is optional. > + */ > + void (*detach)(struct drm_bridge *bridge); > + > + /** > + * @mode_fixup: > + * > + * This callback is used to validate and adjust a mode. The paramater > + * mode is the display mode that should be fed to the next element in > + * the display chain, either the final &drm_connector or the next > + * &drm_bridge. The parameter adjusted_mode is the input mode the bridge > + * requires. It can be modified by this callback and does not need to > + * match mode. > + * > + * This is the only hook that allows a bridge to reject a modeset. If > + * this function passes all other callbacks must succeed for this > + * configuration. > + * > + * The mode_fixup callback is optional. > + * > + * NOTE: > + * > + * This function is called in the check phase of atomic modesets, which > + * can be aborted for any reason (including on userspace's request to > + * just check whether a configuration would be possible). Drivers MUST > + * NOT touch any persistent state (hardware or software) or data > + * structures except the passed in @state parameter. > + * > + * RETURNS: > + * > + * True if an acceptable configuration is possible, false if the modeset > + * operation should be rejected. > + */ > + bool (*mode_fixup)(struct drm_bridge *bridge, > + const struct drm_display_mode *mode, > + struct drm_display_mode *adjusted_mode); > + /** > + * @disable: > + * > + * This callback should disable the bridge. It is called right before > + * the preceding element in the display pipe is disabled. If the > + * preceding element is a bridge this means it's called before that > + * bridge's ->disable() function. If the preceding element is a > + * &drm_encoder it's called right before the encoder's ->disable(), > + * ->prepare() or ->dpms() hook from struct &drm_encoder_helper_funcs. > + * > + * The bridge can assume that the display pipe (i.e. clocks and timing > + * signals) feeding it is still running when this callback is called. > + * > + * The disable callback is optional. > + */ > + void (*disable)(struct drm_bridge *bridge); > + > + /** > + * @post_disable: > + * > + * This callback should disable the bridge. It is called right after > + * the preceding element in the display pipe is disabled. If the > + * preceding element is a bridge this means it's called after that > + * bridge's ->post_disable() function. If the preceding element is a > + * &drm_encoder it's called right after the encoder's ->disable(), > + * ->prepare() or ->dpms() hook from struct &drm_encoder_helper_funcs. > + * > + * The bridge must assume that the display pipe (i.e. clocks and timing > + * singals) feeding it is no longer running when this callback is > + * called. > + * > + * The post_disable callback is optional. > + */ > + void (*post_disable)(struct drm_bridge *bridge); > + > + /** > + * @mode_set: > + * > + * This callback should set the given mode on the bridge. It is called > + * after the ->mode_set() callback for the preceding element in the > + * display pipeline has been called already. The display pipe (i.e. > + * clocks and timing signals) is off when this function is called. > + */ > + void (*mode_set)(struct drm_bridge *bridge, > + struct drm_display_mode *mode, > + struct drm_display_mode *adjusted_mode); > + /** > + * @pre_enable: > + * > + * This callback should enable the bridge. It is called right before > + * the preceding element in the display pipe is enabled. If the > + * preceding element is a bridge this means it's called before that > + * bridge's ->pre_enable() function. If the preceding element is a > + * &drm_encoder it's called right before the encoder's ->enable(), > + * ->commit() or ->dpms() hook from struct &drm_encoder_helper_funcs. > + * > + * The display pipe (i.e. clocks and timing signals) feeding this bridge > + * will not yet be running when this callback is called. The bridge must > + * not enable the display link feeding the next bridge in the chain (if > + * there is one) when this callback is called. > + * > + * The pre_enable callback is optional. > + */ > + void (*pre_enable)(struct drm_bridge *bridge); > + > + /** > + * @enable: > + * > + * This callback should enable the bridge. It is called right after > + * the preceding element in the display pipe is enabled. If the > + * preceding element is a bridge this means it's called after that > + * bridge's ->enable() function. If the preceding element is a > + * &drm_encoder it's called right after the encoder's ->enable(), > + * ->commit() or ->dpms() hook from struct &drm_encoder_helper_funcs. > + * > + * The bridge can assume that the display pipe (i.e. clocks and timing > + * signals) feeding it is running when this callback is called. This > + * callback must enable the display link feeding the next bridge in the > + * chain if there is one. > + * > + * The enable callback is optional. > + */ > + void (*enable)(struct drm_bridge *bridge); > +}; > + > +/** > + * struct drm_bridge - central DRM bridge control structure > + * @dev: DRM device this bridge belongs to > + * @encoder: encoder to which this bridge is connected > + * @next: the next bridge in the encoder chain > + * @of_node: device node pointer to the bridge > + * @list: to keep track of all added bridges > + * @funcs: control functions > + * @driver_private: pointer to the bridge driver's internal context > + */ > +struct drm_bridge { > + struct drm_device *dev; > + struct drm_encoder *encoder; > + struct drm_bridge *next; > +#ifdef CONFIG_OF > + struct device_node *of_node; > +#endif > + struct list_head list; > + > + const struct drm_bridge_funcs *funcs; > + void *driver_private; > +}; > + > +int drm_bridge_add(struct drm_bridge *bridge); > +void drm_bridge_remove(struct drm_bridge *bridge); > +struct drm_bridge *of_drm_find_bridge(struct device_node *np); > +int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge); > +void drm_bridge_detach(struct drm_bridge *bridge); > + > +bool drm_bridge_mode_fixup(struct drm_bridge *bridge, > + const struct drm_display_mode *mode, > + struct drm_display_mode *adjusted_mode); > +void drm_bridge_disable(struct drm_bridge *bridge); > +void drm_bridge_post_disable(struct drm_bridge *bridge); > +void drm_bridge_mode_set(struct drm_bridge *bridge, > + struct drm_display_mode *mode, > + struct drm_display_mode *adjusted_mode); > +void drm_bridge_pre_enable(struct drm_bridge *bridge); > +void drm_bridge_enable(struct drm_bridge *bridge); > + > +#endif > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h > index e4e545e9516d..51a15deda161 100644 > --- a/include/drm/drm_connector.h > +++ b/include/drm/drm_connector.h > @@ -27,6 +27,10 @@ > #include <linux/ctype.h> > #include <drm/drm_mode_object.h> > > +#include <uapi/drm/drm_mode.h> > + > +struct drm_device; > + > struct drm_connector_helper_funcs; > struct drm_device; > struct drm_crtc; > diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h > index 2a642ae96127..bf9ee1b97c26 100644 > --- a/include/drm/drm_crtc.h > +++ b/include/drm/drm_crtc.h > @@ -42,6 +42,7 @@ > #include <drm/drm_connector.h> > #include <drm/drm_encoder.h> > #include <drm/drm_property.h> > +#include <drm/drm_bridge.h> > > struct drm_device; > struct drm_mode_set; > @@ -1001,174 +1002,6 @@ struct drm_plane { > }; > > /** > - * struct drm_bridge_funcs - drm_bridge control functions > - */ > -struct drm_bridge_funcs { > - /** > - * @attach: > - * > - * This callback is invoked whenever our bridge is being attached to a > - * &drm_encoder. > - * > - * The attach callback is optional. > - * > - * RETURNS: > - * > - * Zero on success, error code on failure. > - */ > - int (*attach)(struct drm_bridge *bridge); > - > - /** > - * @detach: > - * > - * This callback is invoked whenever our bridge is being detached from a > - * &drm_encoder. > - * > - * The detach callback is optional. > - */ > - void (*detach)(struct drm_bridge *bridge); > - > - /** > - * @mode_fixup: > - * > - * This callback is used to validate and adjust a mode. The paramater > - * mode is the display mode that should be fed to the next element in > - * the display chain, either the final &drm_connector or the next > - * &drm_bridge. The parameter adjusted_mode is the input mode the bridge > - * requires. It can be modified by this callback and does not need to > - * match mode. > - * > - * This is the only hook that allows a bridge to reject a modeset. If > - * this function passes all other callbacks must succeed for this > - * configuration. > - * > - * The mode_fixup callback is optional. > - * > - * NOTE: > - * > - * This function is called in the check phase of atomic modesets, which > - * can be aborted for any reason (including on userspace's request to > - * just check whether a configuration would be possible). Drivers MUST > - * NOT touch any persistent state (hardware or software) or data > - * structures except the passed in @state parameter. > - * > - * RETURNS: > - * > - * True if an acceptable configuration is possible, false if the modeset > - * operation should be rejected. > - */ > - bool (*mode_fixup)(struct drm_bridge *bridge, > - const struct drm_display_mode *mode, > - struct drm_display_mode *adjusted_mode); > - /** > - * @disable: > - * > - * This callback should disable the bridge. It is called right before > - * the preceding element in the display pipe is disabled. If the > - * preceding element is a bridge this means it's called before that > - * bridge's ->disable() function. If the preceding element is a > - * &drm_encoder it's called right before the encoder's ->disable(), > - * ->prepare() or ->dpms() hook from struct &drm_encoder_helper_funcs. > - * > - * The bridge can assume that the display pipe (i.e. clocks and timing > - * signals) feeding it is still running when this callback is called. > - * > - * The disable callback is optional. > - */ > - void (*disable)(struct drm_bridge *bridge); > - > - /** > - * @post_disable: > - * > - * This callback should disable the bridge. It is called right after > - * the preceding element in the display pipe is disabled. If the > - * preceding element is a bridge this means it's called after that > - * bridge's ->post_disable() function. If the preceding element is a > - * &drm_encoder it's called right after the encoder's ->disable(), > - * ->prepare() or ->dpms() hook from struct &drm_encoder_helper_funcs. > - * > - * The bridge must assume that the display pipe (i.e. clocks and timing > - * singals) feeding it is no longer running when this callback is > - * called. > - * > - * The post_disable callback is optional. > - */ > - void (*post_disable)(struct drm_bridge *bridge); > - > - /** > - * @mode_set: > - * > - * This callback should set the given mode on the bridge. It is called > - * after the ->mode_set() callback for the preceding element in the > - * display pipeline has been called already. The display pipe (i.e. > - * clocks and timing signals) is off when this function is called. > - */ > - void (*mode_set)(struct drm_bridge *bridge, > - struct drm_display_mode *mode, > - struct drm_display_mode *adjusted_mode); > - /** > - * @pre_enable: > - * > - * This callback should enable the bridge. It is called right before > - * the preceding element in the display pipe is enabled. If the > - * preceding element is a bridge this means it's called before that > - * bridge's ->pre_enable() function. If the preceding element is a > - * &drm_encoder it's called right before the encoder's ->enable(), > - * ->commit() or ->dpms() hook from struct &drm_encoder_helper_funcs. > - * > - * The display pipe (i.e. clocks and timing signals) feeding this bridge > - * will not yet be running when this callback is called. The bridge must > - * not enable the display link feeding the next bridge in the chain (if > - * there is one) when this callback is called. > - * > - * The pre_enable callback is optional. > - */ > - void (*pre_enable)(struct drm_bridge *bridge); > - > - /** > - * @enable: > - * > - * This callback should enable the bridge. It is called right after > - * the preceding element in the display pipe is enabled. If the > - * preceding element is a bridge this means it's called after that > - * bridge's ->enable() function. If the preceding element is a > - * &drm_encoder it's called right after the encoder's ->enable(), > - * ->commit() or ->dpms() hook from struct &drm_encoder_helper_funcs. > - * > - * The bridge can assume that the display pipe (i.e. clocks and timing > - * signals) feeding it is running when this callback is called. This > - * callback must enable the display link feeding the next bridge in the > - * chain if there is one. > - * > - * The enable callback is optional. > - */ > - void (*enable)(struct drm_bridge *bridge); > -}; > - > -/** > - * struct drm_bridge - central DRM bridge control structure > - * @dev: DRM device this bridge belongs to > - * @encoder: encoder to which this bridge is connected > - * @next: the next bridge in the encoder chain > - * @of_node: device node pointer to the bridge > - * @list: to keep track of all added bridges > - * @funcs: control functions > - * @driver_private: pointer to the bridge driver's internal context > - */ > -struct drm_bridge { > - struct drm_device *dev; > - struct drm_encoder *encoder; > - struct drm_bridge *next; > -#ifdef CONFIG_OF > - struct device_node *of_node; > -#endif > - struct list_head list; > - > - const struct drm_bridge_funcs *funcs; > - void *driver_private; > -}; > - > -/** > * struct drm_crtc_commit - track modeset commits on a CRTC > * > * This structure is used to track pending modeset changes and atomic commit on > @@ -2188,22 +2021,4 @@ struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, > int hsize, int vsize, int fresh, > bool rb); > > -/* drm_bridge.c */ > -extern int drm_bridge_add(struct drm_bridge *bridge); > -extern void drm_bridge_remove(struct drm_bridge *bridge); > -extern struct drm_bridge *of_drm_find_bridge(struct device_node *np); > -extern int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge); > -extern void drm_bridge_detach(struct drm_bridge *bridge); > - > -bool drm_bridge_mode_fixup(struct drm_bridge *bridge, > - const struct drm_display_mode *mode, > - struct drm_display_mode *adjusted_mode); > -void drm_bridge_disable(struct drm_bridge *bridge); > -void drm_bridge_post_disable(struct drm_bridge *bridge); > -void drm_bridge_mode_set(struct drm_bridge *bridge, > - struct drm_display_mode *mode, > - struct drm_display_mode *adjusted_mode); > -void drm_bridge_pre_enable(struct drm_bridge *bridge); > -void drm_bridge_enable(struct drm_bridge *bridge); > - > #endif /* __DRM_CRTC_H__ */ > diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h > index be3d93839ae2..43460b21d112 100644 > --- a/include/drm/drm_mode_object.h > +++ b/include/drm/drm_mode_object.h > @@ -26,6 +26,7 @@ > #include <linux/kref.h> > struct drm_object_properties; > struct drm_property; > +struct drm_device; > > /** > * struct drm_mode_object - base structure for modeset objects > diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h > index 986ed6ff635a..9934d91619c1 100644 > --- a/include/drm/drm_modes.h > +++ b/include/drm/drm_modes.h > @@ -27,9 +27,13 @@ > #ifndef __DRM_MODES_H__ > #define __DRM_MODES_H__ > > +#include <linux/hdmi.h> > + > #include <drm/drm_mode_object.h> > #include <drm/drm_connector.h> > > +struct videomode; > + > /* > * Note on terminology: here, for brevity and convenience, we refer to connector > * control chips as 'CRTCs'. They can control any type of connector, VGA, LVDS, >
diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst index 59fa3c11efab..48fc5a96bf95 100644 --- a/Documentation/gpu/drm-kms-helpers.rst +++ b/Documentation/gpu/drm-kms-helpers.rst @@ -126,6 +126,13 @@ Default bridge callback sequence .. kernel-doc:: drivers/gpu/drm/drm_bridge.c :doc: bridge callbacks + +Bridge Helper Reference +------------------------- + +.. kernel-doc:: include/drm/drm_bridge.h + :internal: + .. kernel-doc:: drivers/gpu/drm/drm_bridge.c :export: diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index 484046664d6c..0ee052b7c21a 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -23,10 +23,9 @@ #include <linux/err.h> #include <linux/module.h> +#include <linux/mutex.h> -#include <drm/drm_crtc.h> - -#include "drm/drmP.h" +#include <drm/drm_bridge.h> /** * DOC: overview diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h new file mode 100644 index 000000000000..530a1d6e8cde --- /dev/null +++ b/include/drm/drm_bridge.h @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef __DRM_BRIDGE_H__ +#define __DRM_BRIDGE_H__ + +#include <linux/list.h> +#include <linux/ctype.h> +#include <drm/drm_mode_object.h> +#include <drm/drm_modes.h> + +struct drm_bridge; + +/** + * struct drm_bridge_funcs - drm_bridge control functions + */ +struct drm_bridge_funcs { + /** + * @attach: + * + * This callback is invoked whenever our bridge is being attached to a + * &drm_encoder. + * + * The attach callback is optional. + * + * RETURNS: + * + * Zero on success, error code on failure. + */ + int (*attach)(struct drm_bridge *bridge); + + /** + * @detach: + * + * This callback is invoked whenever our bridge is being detached from a + * &drm_encoder. + * + * The detach callback is optional. + */ + void (*detach)(struct drm_bridge *bridge); + + /** + * @mode_fixup: + * + * This callback is used to validate and adjust a mode. The paramater + * mode is the display mode that should be fed to the next element in + * the display chain, either the final &drm_connector or the next + * &drm_bridge. The parameter adjusted_mode is the input mode the bridge + * requires. It can be modified by this callback and does not need to + * match mode. + * + * This is the only hook that allows a bridge to reject a modeset. If + * this function passes all other callbacks must succeed for this + * configuration. + * + * The mode_fixup callback is optional. + * + * NOTE: + * + * This function is called in the check phase of atomic modesets, which + * can be aborted for any reason (including on userspace's request to + * just check whether a configuration would be possible). Drivers MUST + * NOT touch any persistent state (hardware or software) or data + * structures except the passed in @state parameter. + * + * RETURNS: + * + * True if an acceptable configuration is possible, false if the modeset + * operation should be rejected. + */ + bool (*mode_fixup)(struct drm_bridge *bridge, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); + /** + * @disable: + * + * This callback should disable the bridge. It is called right before + * the preceding element in the display pipe is disabled. If the + * preceding element is a bridge this means it's called before that + * bridge's ->disable() function. If the preceding element is a + * &drm_encoder it's called right before the encoder's ->disable(), + * ->prepare() or ->dpms() hook from struct &drm_encoder_helper_funcs. + * + * The bridge can assume that the display pipe (i.e. clocks and timing + * signals) feeding it is still running when this callback is called. + * + * The disable callback is optional. + */ + void (*disable)(struct drm_bridge *bridge); + + /** + * @post_disable: + * + * This callback should disable the bridge. It is called right after + * the preceding element in the display pipe is disabled. If the + * preceding element is a bridge this means it's called after that + * bridge's ->post_disable() function. If the preceding element is a + * &drm_encoder it's called right after the encoder's ->disable(), + * ->prepare() or ->dpms() hook from struct &drm_encoder_helper_funcs. + * + * The bridge must assume that the display pipe (i.e. clocks and timing + * singals) feeding it is no longer running when this callback is + * called. + * + * The post_disable callback is optional. + */ + void (*post_disable)(struct drm_bridge *bridge); + + /** + * @mode_set: + * + * This callback should set the given mode on the bridge. It is called + * after the ->mode_set() callback for the preceding element in the + * display pipeline has been called already. The display pipe (i.e. + * clocks and timing signals) is off when this function is called. + */ + void (*mode_set)(struct drm_bridge *bridge, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); + /** + * @pre_enable: + * + * This callback should enable the bridge. It is called right before + * the preceding element in the display pipe is enabled. If the + * preceding element is a bridge this means it's called before that + * bridge's ->pre_enable() function. If the preceding element is a + * &drm_encoder it's called right before the encoder's ->enable(), + * ->commit() or ->dpms() hook from struct &drm_encoder_helper_funcs. + * + * The display pipe (i.e. clocks and timing signals) feeding this bridge + * will not yet be running when this callback is called. The bridge must + * not enable the display link feeding the next bridge in the chain (if + * there is one) when this callback is called. + * + * The pre_enable callback is optional. + */ + void (*pre_enable)(struct drm_bridge *bridge); + + /** + * @enable: + * + * This callback should enable the bridge. It is called right after + * the preceding element in the display pipe is enabled. If the + * preceding element is a bridge this means it's called after that + * bridge's ->enable() function. If the preceding element is a + * &drm_encoder it's called right after the encoder's ->enable(), + * ->commit() or ->dpms() hook from struct &drm_encoder_helper_funcs. + * + * The bridge can assume that the display pipe (i.e. clocks and timing + * signals) feeding it is running when this callback is called. This + * callback must enable the display link feeding the next bridge in the + * chain if there is one. + * + * The enable callback is optional. + */ + void (*enable)(struct drm_bridge *bridge); +}; + +/** + * struct drm_bridge - central DRM bridge control structure + * @dev: DRM device this bridge belongs to + * @encoder: encoder to which this bridge is connected + * @next: the next bridge in the encoder chain + * @of_node: device node pointer to the bridge + * @list: to keep track of all added bridges + * @funcs: control functions + * @driver_private: pointer to the bridge driver's internal context + */ +struct drm_bridge { + struct drm_device *dev; + struct drm_encoder *encoder; + struct drm_bridge *next; +#ifdef CONFIG_OF + struct device_node *of_node; +#endif + struct list_head list; + + const struct drm_bridge_funcs *funcs; + void *driver_private; +}; + +int drm_bridge_add(struct drm_bridge *bridge); +void drm_bridge_remove(struct drm_bridge *bridge); +struct drm_bridge *of_drm_find_bridge(struct device_node *np); +int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge); +void drm_bridge_detach(struct drm_bridge *bridge); + +bool drm_bridge_mode_fixup(struct drm_bridge *bridge, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); +void drm_bridge_disable(struct drm_bridge *bridge); +void drm_bridge_post_disable(struct drm_bridge *bridge); +void drm_bridge_mode_set(struct drm_bridge *bridge, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); +void drm_bridge_pre_enable(struct drm_bridge *bridge); +void drm_bridge_enable(struct drm_bridge *bridge); + +#endif diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index e4e545e9516d..51a15deda161 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -27,6 +27,10 @@ #include <linux/ctype.h> #include <drm/drm_mode_object.h> +#include <uapi/drm/drm_mode.h> + +struct drm_device; + struct drm_connector_helper_funcs; struct drm_device; struct drm_crtc; diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 2a642ae96127..bf9ee1b97c26 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -42,6 +42,7 @@ #include <drm/drm_connector.h> #include <drm/drm_encoder.h> #include <drm/drm_property.h> +#include <drm/drm_bridge.h> struct drm_device; struct drm_mode_set; @@ -1001,174 +1002,6 @@ struct drm_plane { }; /** - * struct drm_bridge_funcs - drm_bridge control functions - */ -struct drm_bridge_funcs { - /** - * @attach: - * - * This callback is invoked whenever our bridge is being attached to a - * &drm_encoder. - * - * The attach callback is optional. - * - * RETURNS: - * - * Zero on success, error code on failure. - */ - int (*attach)(struct drm_bridge *bridge); - - /** - * @detach: - * - * This callback is invoked whenever our bridge is being detached from a - * &drm_encoder. - * - * The detach callback is optional. - */ - void (*detach)(struct drm_bridge *bridge); - - /** - * @mode_fixup: - * - * This callback is used to validate and adjust a mode. The paramater - * mode is the display mode that should be fed to the next element in - * the display chain, either the final &drm_connector or the next - * &drm_bridge. The parameter adjusted_mode is the input mode the bridge - * requires. It can be modified by this callback and does not need to - * match mode. - * - * This is the only hook that allows a bridge to reject a modeset. If - * this function passes all other callbacks must succeed for this - * configuration. - * - * The mode_fixup callback is optional. - * - * NOTE: - * - * This function is called in the check phase of atomic modesets, which - * can be aborted for any reason (including on userspace's request to - * just check whether a configuration would be possible). Drivers MUST - * NOT touch any persistent state (hardware or software) or data - * structures except the passed in @state parameter. - * - * RETURNS: - * - * True if an acceptable configuration is possible, false if the modeset - * operation should be rejected. - */ - bool (*mode_fixup)(struct drm_bridge *bridge, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); - /** - * @disable: - * - * This callback should disable the bridge. It is called right before - * the preceding element in the display pipe is disabled. If the - * preceding element is a bridge this means it's called before that - * bridge's ->disable() function. If the preceding element is a - * &drm_encoder it's called right before the encoder's ->disable(), - * ->prepare() or ->dpms() hook from struct &drm_encoder_helper_funcs. - * - * The bridge can assume that the display pipe (i.e. clocks and timing - * signals) feeding it is still running when this callback is called. - * - * The disable callback is optional. - */ - void (*disable)(struct drm_bridge *bridge); - - /** - * @post_disable: - * - * This callback should disable the bridge. It is called right after - * the preceding element in the display pipe is disabled. If the - * preceding element is a bridge this means it's called after that - * bridge's ->post_disable() function. If the preceding element is a - * &drm_encoder it's called right after the encoder's ->disable(), - * ->prepare() or ->dpms() hook from struct &drm_encoder_helper_funcs. - * - * The bridge must assume that the display pipe (i.e. clocks and timing - * singals) feeding it is no longer running when this callback is - * called. - * - * The post_disable callback is optional. - */ - void (*post_disable)(struct drm_bridge *bridge); - - /** - * @mode_set: - * - * This callback should set the given mode on the bridge. It is called - * after the ->mode_set() callback for the preceding element in the - * display pipeline has been called already. The display pipe (i.e. - * clocks and timing signals) is off when this function is called. - */ - void (*mode_set)(struct drm_bridge *bridge, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); - /** - * @pre_enable: - * - * This callback should enable the bridge. It is called right before - * the preceding element in the display pipe is enabled. If the - * preceding element is a bridge this means it's called before that - * bridge's ->pre_enable() function. If the preceding element is a - * &drm_encoder it's called right before the encoder's ->enable(), - * ->commit() or ->dpms() hook from struct &drm_encoder_helper_funcs. - * - * The display pipe (i.e. clocks and timing signals) feeding this bridge - * will not yet be running when this callback is called. The bridge must - * not enable the display link feeding the next bridge in the chain (if - * there is one) when this callback is called. - * - * The pre_enable callback is optional. - */ - void (*pre_enable)(struct drm_bridge *bridge); - - /** - * @enable: - * - * This callback should enable the bridge. It is called right after - * the preceding element in the display pipe is enabled. If the - * preceding element is a bridge this means it's called after that - * bridge's ->enable() function. If the preceding element is a - * &drm_encoder it's called right after the encoder's ->enable(), - * ->commit() or ->dpms() hook from struct &drm_encoder_helper_funcs. - * - * The bridge can assume that the display pipe (i.e. clocks and timing - * signals) feeding it is running when this callback is called. This - * callback must enable the display link feeding the next bridge in the - * chain if there is one. - * - * The enable callback is optional. - */ - void (*enable)(struct drm_bridge *bridge); -}; - -/** - * struct drm_bridge - central DRM bridge control structure - * @dev: DRM device this bridge belongs to - * @encoder: encoder to which this bridge is connected - * @next: the next bridge in the encoder chain - * @of_node: device node pointer to the bridge - * @list: to keep track of all added bridges - * @funcs: control functions - * @driver_private: pointer to the bridge driver's internal context - */ -struct drm_bridge { - struct drm_device *dev; - struct drm_encoder *encoder; - struct drm_bridge *next; -#ifdef CONFIG_OF - struct device_node *of_node; -#endif - struct list_head list; - - const struct drm_bridge_funcs *funcs; - void *driver_private; -}; - -/** * struct drm_crtc_commit - track modeset commits on a CRTC * * This structure is used to track pending modeset changes and atomic commit on @@ -2188,22 +2021,4 @@ struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, int hsize, int vsize, int fresh, bool rb); -/* drm_bridge.c */ -extern int drm_bridge_add(struct drm_bridge *bridge); -extern void drm_bridge_remove(struct drm_bridge *bridge); -extern struct drm_bridge *of_drm_find_bridge(struct device_node *np); -extern int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge); -extern void drm_bridge_detach(struct drm_bridge *bridge); - -bool drm_bridge_mode_fixup(struct drm_bridge *bridge, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); -void drm_bridge_disable(struct drm_bridge *bridge); -void drm_bridge_post_disable(struct drm_bridge *bridge); -void drm_bridge_mode_set(struct drm_bridge *bridge, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); -void drm_bridge_pre_enable(struct drm_bridge *bridge); -void drm_bridge_enable(struct drm_bridge *bridge); - #endif /* __DRM_CRTC_H__ */ diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h index be3d93839ae2..43460b21d112 100644 --- a/include/drm/drm_mode_object.h +++ b/include/drm/drm_mode_object.h @@ -26,6 +26,7 @@ #include <linux/kref.h> struct drm_object_properties; struct drm_property; +struct drm_device; /** * struct drm_mode_object - base structure for modeset objects diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h index 986ed6ff635a..9934d91619c1 100644 --- a/include/drm/drm_modes.h +++ b/include/drm/drm_modes.h @@ -27,9 +27,13 @@ #ifndef __DRM_MODES_H__ #define __DRM_MODES_H__ +#include <linux/hdmi.h> + #include <drm/drm_mode_object.h> #include <drm/drm_connector.h> +struct videomode; + /* * Note on terminology: here, for brevity and convenience, we refer to connector * control chips as 'CRTCs'. They can control any type of connector, VGA, LVDS,
We don't want to burry the bridge structures kerneldoc in drm_crtc.h. Cc: Archit Taneja <archit.taneja@gmail.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> --- Documentation/gpu/drm-kms-helpers.rst | 7 ++ drivers/gpu/drm/drm_bridge.c | 5 +- include/drm/drm_bridge.h | 218 ++++++++++++++++++++++++++++++++++ include/drm/drm_connector.h | 4 + include/drm/drm_crtc.h | 187 +---------------------------- include/drm/drm_mode_object.h | 1 + include/drm/drm_modes.h | 4 + 7 files changed, 237 insertions(+), 189 deletions(-) create mode 100644 include/drm/drm_bridge.h