linux/drivers/gpu/drm/drm_bridge.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2014 Samsung Electronics Co., Ltd
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sub license,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice (including the
  12 * next paragraph) shall be included in all copies or substantial portions
  13 * of the Software.
  14 *
  15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  21 * DEALINGS IN THE SOFTWARE.
  22 */
  23
  24#include <linux/err.h>
  25#include <linux/module.h>
  26#include <linux/mutex.h>
  27
  28#include <drm/drm_bridge.h>
  29
  30/**
  31 * DOC: overview
  32 *
  33 * struct &drm_bridge represents a device that hangs on to an encoder. These are
  34 * handy when a regular &drm_encoder entity isn't enough to represent the entire
  35 * encoder chain.
  36 *
  37 * A bridge is always attached to a single &drm_encoder at a time, but can be
  38 * either connected to it directly, or through an intermediate bridge::
  39 *
  40 *     encoder ---> bridge B ---> bridge A
  41 *
  42 * Here, the output of the encoder feeds to bridge B, and that furthers feeds to
  43 * bridge A.
  44 *
  45 * The driver using the bridge is responsible to make the associations between
  46 * the encoder and bridges. Once these links are made, the bridges will
  47 * participate along with encoder functions to perform mode_set/enable/disable
  48 * through the ops provided in &drm_bridge_funcs.
  49 *
  50 * drm_bridge, like drm_panel, aren't drm_mode_object entities like planes,
  51 * CRTCs, encoders or connectors and hence are not visible to userspace. They
  52 * just provide additional hooks to get the desired output at the end of the
  53 * encoder chain.
  54 *
  55 * Bridges can also be chained up using the next pointer in struct &drm_bridge.
  56 *
  57 * Both legacy CRTC helpers and the new atomic modeset helpers support bridges.
  58 */
  59
  60static DEFINE_MUTEX(bridge_lock);
  61static LIST_HEAD(bridge_list);
  62
  63/**
  64 * drm_bridge_add - add the given bridge to the global bridge list
  65 *
  66 * @bridge: bridge control structure
  67 *
  68 * RETURNS:
  69 * Unconditionally returns Zero.
  70 */
  71int drm_bridge_add(struct drm_bridge *bridge)
  72{
  73        mutex_lock(&bridge_lock);
  74        list_add_tail(&bridge->list, &bridge_list);
  75        mutex_unlock(&bridge_lock);
  76
  77        return 0;
  78}
  79EXPORT_SYMBOL(drm_bridge_add);
  80
  81/**
  82 * drm_bridge_remove - remove the given bridge from the global bridge list
  83 *
  84 * @bridge: bridge control structure
  85 */
  86void drm_bridge_remove(struct drm_bridge *bridge)
  87{
  88        mutex_lock(&bridge_lock);
  89        list_del_init(&bridge->list);
  90        mutex_unlock(&bridge_lock);
  91}
  92EXPORT_SYMBOL(drm_bridge_remove);
  93
  94/**
  95 * drm_bridge_attach - associate given bridge to our DRM device
  96 *
  97 * @dev: DRM device
  98 * @bridge: bridge control structure
  99 *
 100 * Called by a kms driver to link one of our encoder/bridge to the given
 101 * bridge.
 102 *
 103 * Note that setting up links between the bridge and our encoder/bridge
 104 * objects needs to be handled by the kms driver itself.
 105 *
 106 * RETURNS:
 107 * Zero on success, error code on failure
 108 */
 109int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge)
 110{
 111        if (!dev || !bridge)
 112                return -EINVAL;
 113
 114        if (bridge->dev)
 115                return -EBUSY;
 116
 117        bridge->dev = dev;
 118
 119        if (bridge->funcs->attach)
 120                return bridge->funcs->attach(bridge);
 121
 122        return 0;
 123}
 124EXPORT_SYMBOL(drm_bridge_attach);
 125
 126/**
 127 * drm_bridge_detach - deassociate given bridge from its DRM device
 128 *
 129 * @bridge: bridge control structure
 130 *
 131 * Called by a kms driver to unlink the given bridge from its DRM device.
 132 *
 133 * Note that tearing down links between the bridge and our encoder/bridge
 134 * objects needs to be handled by the kms driver itself.
 135 */
 136void drm_bridge_detach(struct drm_bridge *bridge)
 137{
 138        if (WARN_ON(!bridge))
 139                return;
 140
 141        if (WARN_ON(!bridge->dev))
 142                return;
 143
 144        if (bridge->funcs->detach)
 145                bridge->funcs->detach(bridge);
 146
 147        bridge->dev = NULL;
 148}
 149EXPORT_SYMBOL(drm_bridge_detach);
 150
 151/**
 152 * DOC: bridge callbacks
 153 *
 154 * The &drm_bridge_funcs ops are populated by the bridge driver. The DRM
 155 * internals (atomic and CRTC helpers) use the helpers defined in drm_bridge.c
 156 * These helpers call a specific &drm_bridge_funcs op for all the bridges
 157 * during encoder configuration.
 158 *
 159 * For detailed specification of the bridge callbacks see &drm_bridge_funcs.
 160 */
 161
 162/**
 163 * drm_bridge_mode_fixup - fixup proposed mode for all bridges in the
 164 *                         encoder chain
 165 * @bridge: bridge control structure
 166 * @mode: desired mode to be set for the bridge
 167 * @adjusted_mode: updated mode that works for this bridge
 168 *
 169 * Calls ->mode_fixup() &drm_bridge_funcs op for all the bridges in the
 170 * encoder chain, starting from the first bridge to the last.
 171 *
 172 * Note: the bridge passed should be the one closest to the encoder
 173 *
 174 * RETURNS:
 175 * true on success, false on failure
 176 */
 177bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
 178                        const struct drm_display_mode *mode,
 179                        struct drm_display_mode *adjusted_mode)
 180{
 181        bool ret = true;
 182
 183        if (!bridge)
 184                return true;
 185
 186        if (bridge->funcs->mode_fixup)
 187                ret = bridge->funcs->mode_fixup(bridge, mode, adjusted_mode);
 188
 189        ret = ret && drm_bridge_mode_fixup(bridge->next, mode, adjusted_mode);
 190
 191        return ret;
 192}
 193EXPORT_SYMBOL(drm_bridge_mode_fixup);
 194
 195/**
 196 * drm_bridge_disable - calls ->disable() &drm_bridge_funcs op for all
 197 *                      bridges in the encoder chain.
 198 * @bridge: bridge control structure
 199 *
 200 * Calls ->disable() &drm_bridge_funcs op for all the bridges in the encoder
 201 * chain, starting from the last bridge to the first. These are called before
 202 * calling the encoder's prepare op.
 203 *
 204 * Note: the bridge passed should be the one closest to the encoder
 205 */
 206void drm_bridge_disable(struct drm_bridge *bridge)
 207{
 208        if (!bridge)
 209                return;
 210
 211        drm_bridge_disable(bridge->next);
 212
 213        if (bridge->funcs->disable)
 214                bridge->funcs->disable(bridge);
 215}
 216EXPORT_SYMBOL(drm_bridge_disable);
 217
 218/**
 219 * drm_bridge_post_disable - calls ->post_disable() &drm_bridge_funcs op for
 220 *                           all bridges in the encoder chain.
 221 * @bridge: bridge control structure
 222 *
 223 * Calls ->post_disable() &drm_bridge_funcs op for all the bridges in the
 224 * encoder chain, starting from the first bridge to the last. These are called
 225 * after completing the encoder's prepare op.
 226 *
 227 * Note: the bridge passed should be the one closest to the encoder
 228 */
 229void drm_bridge_post_disable(struct drm_bridge *bridge)
 230{
 231        if (!bridge)
 232                return;
 233
 234        if (bridge->funcs->post_disable)
 235                bridge->funcs->post_disable(bridge);
 236
 237        drm_bridge_post_disable(bridge->next);
 238}
 239EXPORT_SYMBOL(drm_bridge_post_disable);
 240
 241/**
 242 * drm_bridge_mode_set - set proposed mode for all bridges in the
 243 *                       encoder chain
 244 * @bridge: bridge control structure
 245 * @mode: desired mode to be set for the bridge
 246 * @adjusted_mode: updated mode that works for this bridge
 247 *
 248 * Calls ->mode_set() &drm_bridge_funcs op for all the bridges in the
 249 * encoder chain, starting from the first bridge to the last.
 250 *
 251 * Note: the bridge passed should be the one closest to the encoder
 252 */
 253void drm_bridge_mode_set(struct drm_bridge *bridge,
 254                        struct drm_display_mode *mode,
 255                        struct drm_display_mode *adjusted_mode)
 256{
 257        if (!bridge)
 258                return;
 259
 260        if (bridge->funcs->mode_set)
 261                bridge->funcs->mode_set(bridge, mode, adjusted_mode);
 262
 263        drm_bridge_mode_set(bridge->next, mode, adjusted_mode);
 264}
 265EXPORT_SYMBOL(drm_bridge_mode_set);
 266
 267/**
 268 * drm_bridge_pre_enable - calls ->pre_enable() &drm_bridge_funcs op for all
 269 *                         bridges in the encoder chain.
 270 * @bridge: bridge control structure
 271 *
 272 * Calls ->pre_enable() &drm_bridge_funcs op for all the bridges in the encoder
 273 * chain, starting from the last bridge to the first. These are called
 274 * before calling the encoder's commit op.
 275 *
 276 * Note: the bridge passed should be the one closest to the encoder
 277 */
 278void drm_bridge_pre_enable(struct drm_bridge *bridge)
 279{
 280        if (!bridge)
 281                return;
 282
 283        drm_bridge_pre_enable(bridge->next);
 284
 285        if (bridge->funcs->pre_enable)
 286                bridge->funcs->pre_enable(bridge);
 287}
 288EXPORT_SYMBOL(drm_bridge_pre_enable);
 289
 290/**
 291 * drm_bridge_enable - calls ->enable() &drm_bridge_funcs op for all bridges
 292 *                     in the encoder chain.
 293 * @bridge: bridge control structure
 294 *
 295 * Calls ->enable() &drm_bridge_funcs op for all the bridges in the encoder
 296 * chain, starting from the first bridge to the last. These are called
 297 * after completing the encoder's commit op.
 298 *
 299 * Note that the bridge passed should be the one closest to the encoder
 300 */
 301void drm_bridge_enable(struct drm_bridge *bridge)
 302{
 303        if (!bridge)
 304                return;
 305
 306        if (bridge->funcs->enable)
 307                bridge->funcs->enable(bridge);
 308
 309        drm_bridge_enable(bridge->next);
 310}
 311EXPORT_SYMBOL(drm_bridge_enable);
 312
 313#ifdef CONFIG_OF
 314/**
 315 * of_drm_find_bridge - find the bridge corresponding to the device node in
 316 *                      the global bridge list
 317 *
 318 * @np: device node
 319 *
 320 * RETURNS:
 321 * drm_bridge control struct on success, NULL on failure
 322 */
 323struct drm_bridge *of_drm_find_bridge(struct device_node *np)
 324{
 325        struct drm_bridge *bridge;
 326
 327        mutex_lock(&bridge_lock);
 328
 329        list_for_each_entry(bridge, &bridge_list, list) {
 330                if (bridge->of_node == np) {
 331                        mutex_unlock(&bridge_lock);
 332                        return bridge;
 333                }
 334        }
 335
 336        mutex_unlock(&bridge_lock);
 337        return NULL;
 338}
 339EXPORT_SYMBOL(of_drm_find_bridge);
 340#endif
 341
 342MODULE_AUTHOR("Ajay Kumar <ajaykumar.rs@samsung.com>");
 343MODULE_DESCRIPTION("DRM bridge infrastructure");
 344MODULE_LICENSE("GPL and additional rights");
 345