Subversion Repositories Kolibri OS

Rev

Rev 6937 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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.  
  27. #include <drm/drm_crtc.h>
  28.  
  29. #include "drm/drmP.h"
  30.  
  31. /**
  32.  * DOC: overview
  33.  *
  34.  * struct &drm_bridge represents a device that hangs on to an encoder. These are
  35.  * handy when a regular &drm_encoder entity isn't enough to represent the entire
  36.  * encoder chain.
  37.  *
  38.  * A bridge is always attached to a single &drm_encoder at a time, but can be
  39.  * either connected to it directly, or through an intermediate bridge:
  40.  *
  41.  *     encoder ---> bridge B ---> bridge A
  42.  *
  43.  * Here, the output of the encoder feeds to bridge B, and that furthers feeds to
  44.  * bridge A.
  45.  *
  46.  * The driver using the bridge is responsible to make the associations between
  47.  * the encoder and bridges. Once these links are made, the bridges will
  48.  * participate along with encoder functions to perform mode_set/enable/disable
  49.  * through the ops provided in &drm_bridge_funcs.
  50.  *
  51.  * drm_bridge, like drm_panel, aren't drm_mode_object entities like planes,
  52.  * CRTCs, encoders or connectors and hence are not visible to userspace. They
  53.  * just provide additional hooks to get the desired output at the end of the
  54.  * encoder chain.
  55.  *
  56.  * Bridges can also be chained up using the next pointer in struct &drm_bridge.
  57.  *
  58.  * Both legacy CRTC helpers and the new atomic modeset helpers support bridges.
  59.  */
  60.  
  61. static DEFINE_MUTEX(bridge_lock);
  62. static LIST_HEAD(bridge_list);
  63.  
  64. /**
  65.  * drm_bridge_add - add the given bridge to the global bridge list
  66.  *
  67.  * @bridge: bridge control structure
  68.  *
  69.  * RETURNS:
  70.  * Unconditionally returns Zero.
  71.  */
  72. int drm_bridge_add(struct drm_bridge *bridge)
  73. {
  74.         mutex_lock(&bridge_lock);
  75.         list_add_tail(&bridge->list, &bridge_list);
  76.         mutex_unlock(&bridge_lock);
  77.  
  78.         return 0;
  79. }
  80. EXPORT_SYMBOL(drm_bridge_add);
  81.  
  82. /**
  83.  * drm_bridge_remove - remove the given bridge from the global bridge list
  84.  *
  85.  * @bridge: bridge control structure
  86.  */
  87. void drm_bridge_remove(struct drm_bridge *bridge)
  88. {
  89.         mutex_lock(&bridge_lock);
  90.         list_del_init(&bridge->list);
  91.         mutex_unlock(&bridge_lock);
  92. }
  93. EXPORT_SYMBOL(drm_bridge_remove);
  94.  
  95. /**
  96.  * drm_bridge_attach - associate given bridge to our DRM device
  97.  *
  98.  * @dev: DRM device
  99.  * @bridge: bridge control structure
  100.  *
  101.  * called by a kms driver to link one of our encoder/bridge to the given
  102.  * bridge.
  103.  *
  104.  * Note that setting up links between the bridge and our encoder/bridge
  105.  * objects needs to be handled by the kms driver itself
  106.  *
  107.  * RETURNS:
  108.  * Zero on success, error code on failure
  109.  */
  110. int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge)
  111. {
  112.         if (!dev || !bridge)
  113.                 return -EINVAL;
  114.  
  115.         if (bridge->dev)
  116.                 return -EBUSY;
  117.  
  118.         bridge->dev = dev;
  119.  
  120.         if (bridge->funcs->attach)
  121.                 return bridge->funcs->attach(bridge);
  122.  
  123.         return 0;
  124. }
  125. EXPORT_SYMBOL(drm_bridge_attach);
  126.  
  127. /**
  128.  * DOC: bridge callbacks
  129.  *
  130.  * The &drm_bridge_funcs ops are populated by the bridge driver. The DRM
  131.  * internals (atomic and CRTC helpers) use the helpers defined in drm_bridge.c
  132.  * These helpers call a specific &drm_bridge_funcs op for all the bridges
  133.  * during encoder configuration.
  134.  *
  135.  * For detailed specification of the bridge callbacks see &drm_bridge_funcs.
  136.  */
  137.  
  138. /**
  139.  * drm_bridge_mode_fixup - fixup proposed mode for all bridges in the
  140.  *                         encoder chain
  141.  * @bridge: bridge control structure
  142.  * @mode: desired mode to be set for the bridge
  143.  * @adjusted_mode: updated mode that works for this bridge
  144.  *
  145.  * Calls ->mode_fixup() &drm_bridge_funcs op for all the bridges in the
  146.  * encoder chain, starting from the first bridge to the last.
  147.  *
  148.  * Note: the bridge passed should be the one closest to the encoder
  149.  *
  150.  * RETURNS:
  151.  * true on success, false on failure
  152.  */
  153. bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
  154.                         const struct drm_display_mode *mode,
  155.                         struct drm_display_mode *adjusted_mode)
  156. {
  157.         bool ret = true;
  158.  
  159.         if (!bridge)
  160.                 return true;
  161.  
  162.         if (bridge->funcs->mode_fixup)
  163.                 ret = bridge->funcs->mode_fixup(bridge, mode, adjusted_mode);
  164.  
  165.         ret = ret && drm_bridge_mode_fixup(bridge->next, mode, adjusted_mode);
  166.  
  167.         return ret;
  168. }
  169. EXPORT_SYMBOL(drm_bridge_mode_fixup);
  170.  
  171. /**
  172.  * drm_bridge_disable - calls ->disable() &drm_bridge_funcs op for all
  173.  *                      bridges in the encoder chain.
  174.  * @bridge: bridge control structure
  175.  *
  176.  * Calls ->disable() &drm_bridge_funcs op for all the bridges in the encoder
  177.  * chain, starting from the last bridge to the first. These are called before
  178.  * calling the encoder's prepare op.
  179.  *
  180.  * Note: the bridge passed should be the one closest to the encoder
  181.  */
  182. void drm_bridge_disable(struct drm_bridge *bridge)
  183. {
  184.         if (!bridge)
  185.                 return;
  186.  
  187.         drm_bridge_disable(bridge->next);
  188.  
  189.         if (bridge->funcs->disable)
  190.                 bridge->funcs->disable(bridge);
  191. }
  192. EXPORT_SYMBOL(drm_bridge_disable);
  193.  
  194. /**
  195.  * drm_bridge_post_disable - calls ->post_disable() &drm_bridge_funcs op for
  196.  *                           all bridges in the encoder chain.
  197.  * @bridge: bridge control structure
  198.  *
  199.  * Calls ->post_disable() &drm_bridge_funcs op for all the bridges in the
  200.  * encoder chain, starting from the first bridge to the last. These are called
  201.  * after completing the encoder's prepare op.
  202.  *
  203.  * Note: the bridge passed should be the one closest to the encoder
  204.  */
  205. void drm_bridge_post_disable(struct drm_bridge *bridge)
  206. {
  207.         if (!bridge)
  208.                 return;
  209.  
  210.         if (bridge->funcs->post_disable)
  211.                 bridge->funcs->post_disable(bridge);
  212.  
  213.         drm_bridge_post_disable(bridge->next);
  214. }
  215. EXPORT_SYMBOL(drm_bridge_post_disable);
  216.  
  217. /**
  218.  * drm_bridge_mode_set - set proposed mode for all bridges in the
  219.  *                       encoder chain
  220.  * @bridge: bridge control structure
  221.  * @mode: desired mode to be set for the bridge
  222.  * @adjusted_mode: updated mode that works for this bridge
  223.  *
  224.  * Calls ->mode_set() &drm_bridge_funcs op for all the bridges in the
  225.  * encoder chain, starting from the first bridge to the last.
  226.  *
  227.  * Note: the bridge passed should be the one closest to the encoder
  228.  */
  229. void drm_bridge_mode_set(struct drm_bridge *bridge,
  230.                         struct drm_display_mode *mode,
  231.                         struct drm_display_mode *adjusted_mode)
  232. {
  233.         if (!bridge)
  234.                 return;
  235.  
  236.         if (bridge->funcs->mode_set)
  237.                 bridge->funcs->mode_set(bridge, mode, adjusted_mode);
  238.  
  239.         drm_bridge_mode_set(bridge->next, mode, adjusted_mode);
  240. }
  241. EXPORT_SYMBOL(drm_bridge_mode_set);
  242.  
  243. /**
  244.  * drm_bridge_pre_enable - calls ->pre_enable() &drm_bridge_funcs op for all
  245.  *                         bridges in the encoder chain.
  246.  * @bridge: bridge control structure
  247.  *
  248.  * Calls ->pre_enable() &drm_bridge_funcs op for all the bridges in the encoder
  249.  * chain, starting from the last bridge to the first. These are called
  250.  * before calling the encoder's commit op.
  251.  *
  252.  * Note: the bridge passed should be the one closest to the encoder
  253.  */
  254. void drm_bridge_pre_enable(struct drm_bridge *bridge)
  255. {
  256.         if (!bridge)
  257.                 return;
  258.  
  259.         drm_bridge_pre_enable(bridge->next);
  260.  
  261.         if (bridge->funcs->pre_enable)
  262.                 bridge->funcs->pre_enable(bridge);
  263. }
  264. EXPORT_SYMBOL(drm_bridge_pre_enable);
  265.  
  266. /**
  267.  * drm_bridge_enable - calls ->enable() &drm_bridge_funcs op for all bridges
  268.  *                     in the encoder chain.
  269.  * @bridge: bridge control structure
  270.  *
  271.  * Calls ->enable() &drm_bridge_funcs op for all the bridges in the encoder
  272.  * chain, starting from the first bridge to the last. These are called
  273.  * after completing the encoder's commit op.
  274.  *
  275.  * Note that the bridge passed should be the one closest to the encoder
  276.  */
  277. void drm_bridge_enable(struct drm_bridge *bridge)
  278. {
  279.         if (!bridge)
  280.                 return;
  281.  
  282.         if (bridge->funcs->enable)
  283.                 bridge->funcs->enable(bridge);
  284.  
  285.         drm_bridge_enable(bridge->next);
  286. }
  287. EXPORT_SYMBOL(drm_bridge_enable);
  288.  
  289. #ifdef CONFIG_OF
  290. /**
  291.  * of_drm_find_bridge - find the bridge corresponding to the device node in
  292.  *                      the global bridge list
  293.  *
  294.  * @np: device node
  295.  *
  296.  * RETURNS:
  297.  * drm_bridge control struct on success, NULL on failure
  298.  */
  299. struct drm_bridge *of_drm_find_bridge(struct device_node *np)
  300. {
  301.         struct drm_bridge *bridge;
  302.  
  303.         mutex_lock(&bridge_lock);
  304.  
  305.         list_for_each_entry(bridge, &bridge_list, list) {
  306.                 if (bridge->of_node == np) {
  307.                         mutex_unlock(&bridge_lock);
  308.                         return bridge;
  309.                 }
  310.         }
  311.  
  312.         mutex_unlock(&bridge_lock);
  313.         return NULL;
  314. }
  315. EXPORT_SYMBOL(of_drm_find_bridge);
  316. #endif
  317.  
  318. MODULE_AUTHOR("Ajay Kumar <ajaykumar.rs@samsung.com>");
  319. MODULE_DESCRIPTION("DRM bridge infrastructure");
  320. MODULE_LICENSE("GPL and additional rights");
  321.