LCOV - code coverage report
Current view: top level - drivers/gpu/drm - drm_modeset_helper.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 52 0.0 %
Date: 2023-07-19 18:55:55 Functions: 0 5 0.0 %

          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_framebuffer.h>
      27             : #include <drm/drm_modeset_helper.h>
      28             : #include <drm/drm_plane_helper.h>
      29             : #include <drm/drm_print.h>
      30             : #include <drm/drm_probe_helper.h>
      31             : 
      32             : /**
      33             :  * DOC: aux kms helpers
      34             :  *
      35             :  * This helper library contains various one-off functions which don't really fit
      36             :  * anywhere else in the DRM modeset helper library.
      37             :  */
      38             : 
      39             : /**
      40             :  * drm_helper_move_panel_connectors_to_head() - move panels to the front in the
      41             :  *                                              connector list
      42             :  * @dev: drm device to operate on
      43             :  *
      44             :  * Some userspace presumes that the first connected connector is the main
      45             :  * display, where it's supposed to display e.g. the login screen. For
      46             :  * laptops, this should be the main panel. Use this function to sort all
      47             :  * (eDP/LVDS/DSI) panels to the front of the connector list, instead of
      48             :  * painstakingly trying to initialize them in the right order.
      49             :  */
      50           0 : void drm_helper_move_panel_connectors_to_head(struct drm_device *dev)
      51             : {
      52             :         struct drm_connector *connector, *tmp;
      53             :         struct list_head panel_list;
      54             : 
      55           0 :         INIT_LIST_HEAD(&panel_list);
      56             : 
      57           0 :         spin_lock_irq(&dev->mode_config.connector_list_lock);
      58           0 :         list_for_each_entry_safe(connector, tmp,
      59             :                                  &dev->mode_config.connector_list, head) {
      60           0 :                 if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS ||
      61           0 :                     connector->connector_type == DRM_MODE_CONNECTOR_eDP ||
      62             :                     connector->connector_type == DRM_MODE_CONNECTOR_DSI)
      63           0 :                         list_move_tail(&connector->head, &panel_list);
      64             :         }
      65             : 
      66           0 :         list_splice(&panel_list, &dev->mode_config.connector_list);
      67           0 :         spin_unlock_irq(&dev->mode_config.connector_list_lock);
      68           0 : }
      69             : EXPORT_SYMBOL(drm_helper_move_panel_connectors_to_head);
      70             : 
      71             : /**
      72             :  * drm_helper_mode_fill_fb_struct - fill out framebuffer metadata
      73             :  * @dev: DRM device
      74             :  * @fb: drm_framebuffer object to fill out
      75             :  * @mode_cmd: metadata from the userspace fb creation request
      76             :  *
      77             :  * This helper can be used in a drivers fb_create callback to pre-fill the fb's
      78             :  * metadata fields.
      79             :  */
      80           0 : void drm_helper_mode_fill_fb_struct(struct drm_device *dev,
      81             :                                     struct drm_framebuffer *fb,
      82             :                                     const struct drm_mode_fb_cmd2 *mode_cmd)
      83             : {
      84             :         int i;
      85             : 
      86           0 :         fb->dev = dev;
      87           0 :         fb->format = drm_get_format_info(dev, mode_cmd);
      88           0 :         fb->width = mode_cmd->width;
      89           0 :         fb->height = mode_cmd->height;
      90           0 :         for (i = 0; i < 4; i++) {
      91           0 :                 fb->pitches[i] = mode_cmd->pitches[i];
      92           0 :                 fb->offsets[i] = mode_cmd->offsets[i];
      93             :         }
      94           0 :         fb->modifier = mode_cmd->modifier[0];
      95           0 :         fb->flags = mode_cmd->flags;
      96           0 : }
      97             : EXPORT_SYMBOL(drm_helper_mode_fill_fb_struct);
      98             : 
      99             : /*
     100             :  * This is the minimal list of formats that seem to be safe for modeset use
     101             :  * with all current DRM drivers.  Most hardware can actually support more
     102             :  * formats than this and drivers may specify a more accurate list when
     103             :  * creating the primary plane.
     104             :  */
     105             : static const uint32_t safe_modeset_formats[] = {
     106             :         DRM_FORMAT_XRGB8888,
     107             :         DRM_FORMAT_ARGB8888,
     108             : };
     109             : 
     110             : static const struct drm_plane_funcs primary_plane_funcs = {
     111             :         DRM_PLANE_NON_ATOMIC_FUNCS,
     112             : };
     113             : 
     114             : /**
     115             :  * drm_crtc_init - Legacy CRTC initialization function
     116             :  * @dev: DRM device
     117             :  * @crtc: CRTC object to init
     118             :  * @funcs: callbacks for the new CRTC
     119             :  *
     120             :  * Initialize a CRTC object with a default helper-provided primary plane and no
     121             :  * cursor plane.
     122             :  *
     123             :  * Note that we make some assumptions about hardware limitations that may not be
     124             :  * true for all hardware:
     125             :  *
     126             :  * 1. Primary plane cannot be repositioned.
     127             :  * 2. Primary plane cannot be scaled.
     128             :  * 3. Primary plane must cover the entire CRTC.
     129             :  * 4. Subpixel positioning is not supported.
     130             :  * 5. The primary plane must always be on if the CRTC is enabled.
     131             :  *
     132             :  * This is purely a backwards compatibility helper for old drivers. Drivers
     133             :  * should instead implement their own primary plane. Atomic drivers must do so.
     134             :  * Drivers with the above hardware restriction can look into using &struct
     135             :  * drm_simple_display_pipe, which encapsulates the above limitations into a nice
     136             :  * interface.
     137             :  *
     138             :  * Returns:
     139             :  * Zero on success, error code on failure.
     140             :  */
     141           0 : int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
     142             :                   const struct drm_crtc_funcs *funcs)
     143             : {
     144             :         struct drm_plane *primary;
     145             :         int ret;
     146             : 
     147             :         /* possible_crtc's will be filled in later by crtc_init */
     148           0 :         primary = __drm_universal_plane_alloc(dev, sizeof(*primary), 0, 0,
     149             :                                               &primary_plane_funcs,
     150             :                                               safe_modeset_formats,
     151             :                                               ARRAY_SIZE(safe_modeset_formats),
     152             :                                               NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
     153           0 :         if (IS_ERR(primary))
     154           0 :                 return PTR_ERR(primary);
     155             : 
     156             :         /*
     157             :          * Remove the format_default field from drm_plane when dropping
     158             :          * this helper.
     159             :          */
     160           0 :         primary->format_default = true;
     161             : 
     162           0 :         ret = drm_crtc_init_with_planes(dev, crtc, primary, NULL, funcs, NULL);
     163           0 :         if (ret)
     164             :                 goto err_drm_plane_cleanup;
     165             : 
     166             :         return 0;
     167             : 
     168             : err_drm_plane_cleanup:
     169           0 :         drm_plane_cleanup(primary);
     170           0 :         kfree(primary);
     171           0 :         return ret;
     172             : }
     173             : EXPORT_SYMBOL(drm_crtc_init);
     174             : 
     175             : /**
     176             :  * drm_mode_config_helper_suspend - Modeset suspend helper
     177             :  * @dev: DRM device
     178             :  *
     179             :  * This helper function takes care of suspending the modeset side. It disables
     180             :  * output polling if initialized, suspends fbdev if used and finally calls
     181             :  * drm_atomic_helper_suspend().
     182             :  * If suspending fails, fbdev and polling is re-enabled.
     183             :  *
     184             :  * Returns:
     185             :  * Zero on success, negative error code on error.
     186             :  *
     187             :  * See also:
     188             :  * drm_kms_helper_poll_disable() and drm_fb_helper_set_suspend_unlocked().
     189             :  */
     190           0 : int drm_mode_config_helper_suspend(struct drm_device *dev)
     191             : {
     192             :         struct drm_atomic_state *state;
     193             : 
     194           0 :         if (!dev)
     195             :                 return 0;
     196             : 
     197           0 :         drm_kms_helper_poll_disable(dev);
     198           0 :         drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 1);
     199           0 :         state = drm_atomic_helper_suspend(dev);
     200           0 :         if (IS_ERR(state)) {
     201           0 :                 drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 0);
     202           0 :                 drm_kms_helper_poll_enable(dev);
     203           0 :                 return PTR_ERR(state);
     204             :         }
     205             : 
     206           0 :         dev->mode_config.suspend_state = state;
     207             : 
     208           0 :         return 0;
     209             : }
     210             : EXPORT_SYMBOL(drm_mode_config_helper_suspend);
     211             : 
     212             : /**
     213             :  * drm_mode_config_helper_resume - Modeset resume helper
     214             :  * @dev: DRM device
     215             :  *
     216             :  * This helper function takes care of resuming the modeset side. It calls
     217             :  * drm_atomic_helper_resume(), resumes fbdev if used and enables output polling
     218             :  * if initiaized.
     219             :  *
     220             :  * Returns:
     221             :  * Zero on success, negative error code on error.
     222             :  *
     223             :  * See also:
     224             :  * drm_fb_helper_set_suspend_unlocked() and drm_kms_helper_poll_enable().
     225             :  */
     226           0 : int drm_mode_config_helper_resume(struct drm_device *dev)
     227             : {
     228             :         int ret;
     229             : 
     230           0 :         if (!dev)
     231             :                 return 0;
     232             : 
     233           0 :         if (WARN_ON(!dev->mode_config.suspend_state))
     234             :                 return -EINVAL;
     235             : 
     236           0 :         ret = drm_atomic_helper_resume(dev, dev->mode_config.suspend_state);
     237           0 :         if (ret)
     238           0 :                 DRM_ERROR("Failed to resume (%d)\n", ret);
     239           0 :         dev->mode_config.suspend_state = NULL;
     240             : 
     241           0 :         drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 0);
     242           0 :         drm_kms_helper_poll_enable(dev);
     243             : 
     244           0 :         return ret;
     245             : }
     246             : EXPORT_SYMBOL(drm_mode_config_helper_resume);

Generated by: LCOV version 1.14