[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