[PATCH V7 03/12] drm/bridge: Add helper functions for drm_bridge

Sean Paul seanpaul at chromium.org
Mon Oct 27 13:11:57 PDT 2014


On Wed, Aug 27, 2014 at 10:29 AM, Ajay Kumar <ajaykumar.rs at samsung.com> wrote:
> A set of helper functions are defined in this patch to make
> bridge driver probe independent of the drm flow.
>
> The bridge devices register themselves on a lookup table
> when they get probed by calling "drm_bridge_add".
>
> The parent encoder driver waits till the bridge is available
> in the lookup table(by calling "of_drm_find_bridge") and then
> continues with its initialization.
>
> The encoder driver should also call "drm_bridge_attach" to pass
> on the drm_device, encoder pointers to the bridge object.
>
> drm_bridge_attach inturn calls drm_bridge_init to register itself
> with the drm core. Later, it calls "bridge->funcs->attach" so that
> bridge can continue with other initializations.
>
> Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
> ---
>  drivers/gpu/drm/Makefile               |    1 +
>  drivers/gpu/drm/bridge/Kconfig         |   15 ++++-
>  drivers/gpu/drm/drm_bridge.c           |  102 ++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/drm_crtc.c             |    4 +-
>  drivers/gpu/drm/msm/hdmi/hdmi_bridge.c |    4 +-
>  include/drm/drm_crtc.h                 |   12 +++-
>  6 files changed, 131 insertions(+), 7 deletions(-)
>  create mode 100644 drivers/gpu/drm/drm_bridge.c
>
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index 4a55d59..bdbfb6f 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -19,6 +19,7 @@ drm-y       :=        drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \
>  drm-$(CONFIG_COMPAT) += drm_ioc32.o
>  drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
>  drm-$(CONFIG_PCI) += ati_pcigart.o
> +drm-$(CONFIG_DRM_BRIDGE) += drm_bridge.o
>  drm-$(CONFIG_DRM_PANEL) += drm_panel.o
>  drm-$(CONFIG_OF) += drm_of.o
>
> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> index 884923f..5a8e907 100644
> --- a/drivers/gpu/drm/bridge/Kconfig
> +++ b/drivers/gpu/drm/bridge/Kconfig
> @@ -1,5 +1,16 @@
> -config DRM_PTN3460
> -       tristate "PTN3460 DP/LVDS bridge"
> +config DRM_BRIDGE

I'm not convinced this adds any value, to be honest. In addition to
whether or not it's useful, it seems like you'd need to stub the
drm_bridge_* functions that are declared in drm_crtc.h or break them
out into drm_bridge.h.

Sean

> +       tristate
>         depends on DRM
>         select DRM_KMS_HELPER
> +       help
> +         Bridge registration and lookup framework.
> +
> +menu "bridge chips"
> +       depends on DRM_BRIDGE
> +
> +config DRM_PTN3460
> +       tristate "PTN3460 DP/LVDS bridge"
> +       depends on DRM_BRIDGE
>         ---help---
> +
> +endmenu
> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> new file mode 100644
> index 0000000..b2d43fd
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_bridge.c
> @@ -0,0 +1,102 @@
> +/*
> + * Copyright (c) 2014 Samsung Electronics Co., Ltd
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sub license,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the
> + * next paragraph) shall be included in all copies or substantial portions
> + * of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + */
> +
> +#include <linux/err.h>
> +#include <linux/module.h>
> +
> +#include <drm/drm_crtc.h>
> +
> +#include "drm/drmP.h"
> +
> +static DEFINE_MUTEX(bridge_lock);
> +static LIST_HEAD(bridge_list);
> +
> +int drm_bridge_add(struct drm_bridge *bridge)
> +{
> +       mutex_lock(&bridge_lock);
> +       list_add_tail(&bridge->list, &bridge_list);
> +       mutex_unlock(&bridge_lock);
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL(drm_bridge_add);
> +
> +void drm_bridge_remove(struct drm_bridge *bridge)
> +{
> +       mutex_lock(&bridge_lock);
> +       list_del_init(&bridge->list);
> +       mutex_unlock(&bridge_lock);
> +}
> +EXPORT_SYMBOL(drm_bridge_remove);
> +
> +int drm_bridge_attach(struct drm_bridge *bridge,
> +                               struct drm_encoder *encoder)
> +{
> +       int ret;
> +
> +       if (!bridge || !encoder)
> +               return -EINVAL;
> +
> +       if (bridge->encoder)
> +               return -EBUSY;
> +
> +       encoder->bridge = bridge;
> +       bridge->encoder = encoder;
> +       bridge->drm = encoder->dev;
> +
> +       ret = drm_bridge_init(bridge->drm, bridge);
> +       if (ret) {
> +               DRM_ERROR("Failed to register bridge with drm\n");
> +               return ret;
> +       }
> +
> +       if (bridge->funcs->attach)
> +               return bridge->funcs->attach(bridge);
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL(drm_bridge_attach);
> +
> +#ifdef CONFIG_OF
> +struct drm_bridge *of_drm_find_bridge(struct device_node *np)
> +{
> +       struct drm_bridge *bridge;
> +
> +       mutex_lock(&bridge_lock);
> +
> +       list_for_each_entry(bridge, &bridge_list, list) {
> +               if (bridge->dev->of_node == np) {
> +                       mutex_unlock(&bridge_lock);
> +                       return bridge;
> +               }
> +       }
> +
> +       mutex_unlock(&bridge_lock);
> +       return NULL;
> +}
> +EXPORT_SYMBOL(of_drm_find_bridge);
> +#endif
> +
> +MODULE_AUTHOR("Ajay Kumar <ajaykumar.rs at samsung.com>");
> +MODULE_DESCRIPTION("DRM bridge infrastructure");
> +MODULE_LICENSE("GPL and additional rights");
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index 25f5cfa..2fb22fa 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -1039,7 +1039,7 @@ int drm_bridge_init(struct drm_device *dev, struct drm_bridge *bridge)
>         if (ret)
>                 goto out;
>
> -       bridge->dev = dev;
> +       bridge->drm = dev;
>
>         list_add_tail(&bridge->head, &dev->mode_config.bridge_list);
>         dev->mode_config.num_bridge++;
> @@ -1058,7 +1058,7 @@ EXPORT_SYMBOL(drm_bridge_init);
>   */
>  void drm_bridge_cleanup(struct drm_bridge *bridge)
>  {
> -       struct drm_device *dev = bridge->dev;
> +       struct drm_device *dev = bridge->drm;
>
>         drm_modeset_lock_all(dev);
>         drm_mode_object_put(dev, &bridge->base);
> diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
> index 0309539..bc9e5ff 100644
> --- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
> +++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
> @@ -33,7 +33,7 @@ static void hdmi_bridge_destroy(struct drm_bridge *bridge)
>
>  static void power_on(struct drm_bridge *bridge)
>  {
> -       struct drm_device *dev = bridge->dev;
> +       struct drm_device *dev = bridge->drm;
>         struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
>         struct hdmi *hdmi = hdmi_bridge->hdmi;
>         const struct hdmi_platform_config *config = hdmi->config;
> @@ -67,7 +67,7 @@ static void power_on(struct drm_bridge *bridge)
>
>  static void power_off(struct drm_bridge *bridge)
>  {
> -       struct drm_device *dev = bridge->dev;
> +       struct drm_device *dev = bridge->drm;
>         struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
>         struct hdmi *hdmi = hdmi_bridge->hdmi;
>         const struct hdmi_platform_config *config = hdmi->config;
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index f48a436..f6f426f 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -629,6 +629,7 @@ struct drm_plane {
>
>  /**
>   * drm_bridge_funcs - drm_bridge control functions
> + * @attach: Called during drm_bridge_attach
>   * @mode_fixup: Try to fixup (or reject entirely) proposed mode for this bridge
>   * @disable: Called right before encoder prepare, disables the bridge
>   * @post_disable: Called right after encoder prepare, for lockstepped disable
> @@ -638,6 +639,7 @@ struct drm_plane {
>   * @destroy: make object go away
>   */
>  struct drm_bridge_funcs {
> +       int (*attach)(struct drm_bridge *bridge);
>         bool (*mode_fixup)(struct drm_bridge *bridge,
>                            const struct drm_display_mode *mode,
>                            struct drm_display_mode *adjusted_mode);
> @@ -660,8 +662,11 @@ struct drm_bridge_funcs {
>   * @driver_private: pointer to the bridge driver's internal context
>   */
>  struct drm_bridge {
> -       struct drm_device *dev;
> +       struct device *dev;
> +       struct drm_device *drm;
> +       struct drm_encoder *encoder;
>         struct list_head head;
> +       struct list_head list;
>
>         struct drm_mode_object base;
>
> @@ -906,6 +911,11 @@ extern void drm_connector_cleanup(struct drm_connector *connector);
>  /* helper to unplug all connectors from sysfs for device */
>  extern void drm_connector_unplug_all(struct drm_device *dev);
>
> +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_bridge *bridge,
> +                               struct drm_encoder *encoder);
>  extern int drm_bridge_init(struct drm_device *dev, struct drm_bridge *bridge);
>  extern void drm_bridge_cleanup(struct drm_bridge *bridge);
>
> --
> 1.7.9.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


More information about the dri-devel mailing list