LCOV - code coverage report
Current view: top level - drivers/gpu/drm - drm_modeset_helper.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 63 0.0 %
Date: 2022-04-01 13:59:58 Functions: 0 6 0.0 %
Branches: 0 26 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2016 Intel Corporation
       3                 :            :  *
       4                 :            :  * Permission to use, copy, modify, distribute, and sell this software and its
       5                 :            :  * documentation for any purpose is hereby granted without fee, provided that
       6                 :            :  * the above copyright notice appear in all copies and that both that copyright
       7                 :            :  * notice and this permission notice appear in supporting documentation, and
       8                 :            :  * that the name of the copyright holders not be used in advertising or
       9                 :            :  * publicity pertaining to distribution of the software without specific,
      10                 :            :  * written prior permission.  The copyright holders make no representations
      11                 :            :  * about the suitability of this software for any purpose.  It is provided "as
      12                 :            :  * is" without express or implied warranty.
      13                 :            :  *
      14                 :            :  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
      15                 :            :  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
      16                 :            :  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
      17                 :            :  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
      18                 :            :  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
      19                 :            :  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
      20                 :            :  * OF THIS SOFTWARE.
      21                 :            :  */
      22                 :            : 
      23                 :            : #include <drm/drm_atomic_helper.h>
      24                 :            : #include <drm/drm_fb_helper.h>
      25                 :            : #include <drm/drm_fourcc.h>
      26                 :            : #include <drm/drm_modeset_helper.h>
      27                 :            : #include <drm/drm_plane_helper.h>
      28                 :            : #include <drm/drm_print.h>
      29                 :            : #include <drm/drm_probe_helper.h>
      30                 :            : 
      31                 :            : /**
      32                 :            :  * DOC: aux kms helpers
      33                 :            :  *
      34                 :            :  * This helper library contains various one-off functions which don't really fit
      35                 :            :  * anywhere else in the DRM modeset helper library.
      36                 :            :  */
      37                 :            : 
      38                 :            : /**
      39                 :            :  * drm_helper_move_panel_connectors_to_head() - move panels to the front in the
      40                 :            :  *                                              connector list
      41                 :            :  * @dev: drm device to operate on
      42                 :            :  *
      43                 :            :  * Some userspace presumes that the first connected connector is the main
      44                 :            :  * display, where it's supposed to display e.g. the login screen. For
      45                 :            :  * laptops, this should be the main panel. Use this function to sort all
      46                 :            :  * (eDP/LVDS/DSI) panels to the front of the connector list, instead of
      47                 :            :  * painstakingly trying to initialize them in the right order.
      48                 :            :  */
      49                 :          0 : void drm_helper_move_panel_connectors_to_head(struct drm_device *dev)
      50                 :            : {
      51                 :          0 :         struct drm_connector *connector, *tmp;
      52                 :          0 :         struct list_head panel_list;
      53                 :            : 
      54                 :          0 :         INIT_LIST_HEAD(&panel_list);
      55                 :            : 
      56                 :          0 :         spin_lock_irq(&dev->mode_config.connector_list_lock);
      57         [ #  # ]:          0 :         list_for_each_entry_safe(connector, tmp,
      58                 :            :                                  &dev->mode_config.connector_list, head) {
      59         [ #  # ]:          0 :                 if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS ||
      60         [ #  # ]:          0 :                     connector->connector_type == DRM_MODE_CONNECTOR_eDP ||
      61                 :            :                     connector->connector_type == DRM_MODE_CONNECTOR_DSI)
      62                 :          0 :                         list_move_tail(&connector->head, &panel_list);
      63                 :            :         }
      64                 :            : 
      65         [ #  # ]:          0 :         list_splice(&panel_list, &dev->mode_config.connector_list);
      66                 :          0 :         spin_unlock_irq(&dev->mode_config.connector_list_lock);
      67                 :          0 : }
      68                 :            : EXPORT_SYMBOL(drm_helper_move_panel_connectors_to_head);
      69                 :            : 
      70                 :            : /**
      71                 :            :  * drm_helper_mode_fill_fb_struct - fill out framebuffer metadata
      72                 :            :  * @dev: DRM device
      73                 :            :  * @fb: drm_framebuffer object to fill out
      74                 :            :  * @mode_cmd: metadata from the userspace fb creation request
      75                 :            :  *
      76                 :            :  * This helper can be used in a drivers fb_create callback to pre-fill the fb's
      77                 :            :  * metadata fields.
      78                 :            :  */
      79                 :          0 : void drm_helper_mode_fill_fb_struct(struct drm_device *dev,
      80                 :            :                                     struct drm_framebuffer *fb,
      81                 :            :                                     const struct drm_mode_fb_cmd2 *mode_cmd)
      82                 :            : {
      83                 :          0 :         int i;
      84                 :            : 
      85                 :          0 :         fb->dev = dev;
      86                 :          0 :         fb->format = drm_get_format_info(dev, mode_cmd);
      87                 :          0 :         fb->width = mode_cmd->width;
      88                 :          0 :         fb->height = mode_cmd->height;
      89         [ #  # ]:          0 :         for (i = 0; i < 4; i++) {
      90                 :          0 :                 fb->pitches[i] = mode_cmd->pitches[i];
      91                 :          0 :                 fb->offsets[i] = mode_cmd->offsets[i];
      92                 :            :         }
      93                 :          0 :         fb->modifier = mode_cmd->modifier[0];
      94                 :          0 :         fb->flags = mode_cmd->flags;
      95                 :          0 : }
      96                 :            : EXPORT_SYMBOL(drm_helper_mode_fill_fb_struct);
      97                 :            : 
      98                 :            : /*
      99                 :            :  * This is the minimal list of formats that seem to be safe for modeset use
     100                 :            :  * with all current DRM drivers.  Most hardware can actually support more
     101                 :            :  * formats than this and drivers may specify a more accurate list when
     102                 :            :  * creating the primary plane.  However drivers that still call
     103                 :            :  * drm_plane_init() will use this minimal format list as the default.
     104                 :            :  */
     105                 :            : static const uint32_t safe_modeset_formats[] = {
     106                 :            :         DRM_FORMAT_XRGB8888,
     107                 :            :         DRM_FORMAT_ARGB8888,
     108                 :            : };
     109                 :            : 
     110                 :          0 : static struct drm_plane *create_primary_plane(struct drm_device *dev)
     111                 :            : {
     112                 :          0 :         struct drm_plane *primary;
     113                 :          0 :         int ret;
     114                 :            : 
     115                 :          0 :         primary = kzalloc(sizeof(*primary), GFP_KERNEL);
     116         [ #  # ]:          0 :         if (primary == NULL) {
     117                 :          0 :                 DRM_DEBUG_KMS("Failed to allocate primary plane\n");
     118                 :          0 :                 return NULL;
     119                 :            :         }
     120                 :            : 
     121                 :            :         /*
     122                 :            :          * Remove the format_default field from drm_plane when dropping
     123                 :            :          * this helper.
     124                 :            :          */
     125                 :          0 :         primary->format_default = true;
     126                 :            : 
     127                 :            :         /* possible_crtc's will be filled in later by crtc_init */
     128                 :          0 :         ret = drm_universal_plane_init(dev, primary, 0,
     129                 :            :                                        &drm_primary_helper_funcs,
     130                 :            :                                        safe_modeset_formats,
     131                 :            :                                        ARRAY_SIZE(safe_modeset_formats),
     132                 :            :                                        NULL,
     133                 :            :                                        DRM_PLANE_TYPE_PRIMARY, NULL);
     134         [ #  # ]:          0 :         if (ret) {
     135                 :          0 :                 kfree(primary);
     136                 :          0 :                 primary = NULL;
     137                 :            :         }
     138                 :            : 
     139                 :            :         return primary;
     140                 :            : }
     141                 :            : 
     142                 :            : /**
     143                 :            :  * drm_crtc_init - Legacy CRTC initialization function
     144                 :            :  * @dev: DRM device
     145                 :            :  * @crtc: CRTC object to init
     146                 :            :  * @funcs: callbacks for the new CRTC
     147                 :            :  *
     148                 :            :  * Initialize a CRTC object with a default helper-provided primary plane and no
     149                 :            :  * cursor plane.
     150                 :            :  *
     151                 :            :  * Note that we make some assumptions about hardware limitations that may not be
     152                 :            :  * true for all hardware:
     153                 :            :  *
     154                 :            :  * 1. Primary plane cannot be repositioned.
     155                 :            :  * 2. Primary plane cannot be scaled.
     156                 :            :  * 3. Primary plane must cover the entire CRTC.
     157                 :            :  * 4. Subpixel positioning is not supported.
     158                 :            :  * 5. The primary plane must always be on if the CRTC is enabled.
     159                 :            :  *
     160                 :            :  * This is purely a backwards compatibility helper for old drivers. Drivers
     161                 :            :  * should instead implement their own primary plane. Atomic drivers must do so.
     162                 :            :  * Drivers with the above hardware restriction can look into using &struct
     163                 :            :  * drm_simple_display_pipe, which encapsulates the above limitations into a nice
     164                 :            :  * interface.
     165                 :            :  *
     166                 :            :  * Returns:
     167                 :            :  * Zero on success, error code on failure.
     168                 :            :  */
     169                 :          0 : int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
     170                 :            :                   const struct drm_crtc_funcs *funcs)
     171                 :            : {
     172                 :          0 :         struct drm_plane *primary;
     173                 :            : 
     174                 :          0 :         primary = create_primary_plane(dev);
     175                 :          0 :         return drm_crtc_init_with_planes(dev, crtc, primary, NULL, funcs,
     176                 :            :                                          NULL);
     177                 :            : }
     178                 :            : EXPORT_SYMBOL(drm_crtc_init);
     179                 :            : 
     180                 :            : /**
     181                 :            :  * drm_mode_config_helper_suspend - Modeset suspend helper
     182                 :            :  * @dev: DRM device
     183                 :            :  *
     184                 :            :  * This helper function takes care of suspending the modeset side. It disables
     185                 :            :  * output polling if initialized, suspends fbdev if used and finally calls
     186                 :            :  * drm_atomic_helper_suspend().
     187                 :            :  * If suspending fails, fbdev and polling is re-enabled.
     188                 :            :  *
     189                 :            :  * Returns:
     190                 :            :  * Zero on success, negative error code on error.
     191                 :            :  *
     192                 :            :  * See also:
     193                 :            :  * drm_kms_helper_poll_disable() and drm_fb_helper_set_suspend_unlocked().
     194                 :            :  */
     195                 :          0 : int drm_mode_config_helper_suspend(struct drm_device *dev)
     196                 :            : {
     197                 :          0 :         struct drm_atomic_state *state;
     198                 :            : 
     199         [ #  # ]:          0 :         if (!dev)
     200                 :            :                 return 0;
     201                 :            : 
     202                 :          0 :         drm_kms_helper_poll_disable(dev);
     203                 :          0 :         drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 1);
     204                 :          0 :         state = drm_atomic_helper_suspend(dev);
     205         [ #  # ]:          0 :         if (IS_ERR(state)) {
     206                 :          0 :                 drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 0);
     207                 :          0 :                 drm_kms_helper_poll_enable(dev);
     208                 :          0 :                 return PTR_ERR(state);
     209                 :            :         }
     210                 :            : 
     211                 :          0 :         dev->mode_config.suspend_state = state;
     212                 :            : 
     213                 :          0 :         return 0;
     214                 :            : }
     215                 :            : EXPORT_SYMBOL(drm_mode_config_helper_suspend);
     216                 :            : 
     217                 :            : /**
     218                 :            :  * drm_mode_config_helper_resume - Modeset resume helper
     219                 :            :  * @dev: DRM device
     220                 :            :  *
     221                 :            :  * This helper function takes care of resuming the modeset side. It calls
     222                 :            :  * drm_atomic_helper_resume(), resumes fbdev if used and enables output polling
     223                 :            :  * if initiaized.
     224                 :            :  *
     225                 :            :  * Returns:
     226                 :            :  * Zero on success, negative error code on error.
     227                 :            :  *
     228                 :            :  * See also:
     229                 :            :  * drm_fb_helper_set_suspend_unlocked() and drm_kms_helper_poll_enable().
     230                 :            :  */
     231                 :          0 : int drm_mode_config_helper_resume(struct drm_device *dev)
     232                 :            : {
     233                 :          0 :         int ret;
     234                 :            : 
     235         [ #  # ]:          0 :         if (!dev)
     236                 :            :                 return 0;
     237                 :            : 
     238   [ #  #  #  # ]:          0 :         if (WARN_ON(!dev->mode_config.suspend_state))
     239                 :            :                 return -EINVAL;
     240                 :            : 
     241                 :          0 :         ret = drm_atomic_helper_resume(dev, dev->mode_config.suspend_state);
     242         [ #  # ]:          0 :         if (ret)
     243                 :          0 :                 DRM_ERROR("Failed to resume (%d)\n", ret);
     244                 :          0 :         dev->mode_config.suspend_state = NULL;
     245                 :            : 
     246                 :          0 :         drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 0);
     247                 :          0 :         drm_kms_helper_poll_enable(dev);
     248                 :            : 
     249                 :          0 :         return ret;
     250                 :            : }
     251                 :            : EXPORT_SYMBOL(drm_mode_config_helper_resume);

Generated by: LCOV version 1.14