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

Ajay kumar ajaynumb at gmail.com
Tue Oct 28 02:22:16 PDT 2014


On Tue, Oct 28, 2014 at 1:41 AM, Sean Paul <seanpaul at chromium.org> wrote:
> 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