drm_modeset_helper.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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. #include <drm/drm_modeset_helper.h>
  23. #include <drm/drm_plane_helper.h>
  24. /**
  25. * DOC: aux kms helpers
  26. *
  27. * This helper library contains various one-off functions which don't really fit
  28. * anywhere else in the DRM modeset helper library.
  29. */
  30. /**
  31. * drm_helper_move_panel_connectors_to_head() - move panels to the front in the
  32. * connector list
  33. * @dev: drm device to operate on
  34. *
  35. * Some userspace presumes that the first connected connector is the main
  36. * display, where it's supposed to display e.g. the login screen. For
  37. * laptops, this should be the main panel. Use this function to sort all
  38. * (eDP/LVDS) panels to the front of the connector list, instead of
  39. * painstakingly trying to initialize them in the right order.
  40. */
  41. void drm_helper_move_panel_connectors_to_head(struct drm_device *dev)
  42. {
  43. struct drm_connector *connector, *tmp;
  44. struct list_head panel_list;
  45. INIT_LIST_HEAD(&panel_list);
  46. list_for_each_entry_safe(connector, tmp,
  47. &dev->mode_config.connector_list, head) {
  48. if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS ||
  49. connector->connector_type == DRM_MODE_CONNECTOR_eDP)
  50. list_move_tail(&connector->head, &panel_list);
  51. }
  52. list_splice(&panel_list, &dev->mode_config.connector_list);
  53. }
  54. EXPORT_SYMBOL(drm_helper_move_panel_connectors_to_head);
  55. /**
  56. * drm_helper_mode_fill_fb_struct - fill out framebuffer metadata
  57. * @fb: drm_framebuffer object to fill out
  58. * @mode_cmd: metadata from the userspace fb creation request
  59. *
  60. * This helper can be used in a drivers fb_create callback to pre-fill the fb's
  61. * metadata fields.
  62. */
  63. void drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
  64. const struct drm_mode_fb_cmd2 *mode_cmd)
  65. {
  66. const struct drm_format_info *info;
  67. int i;
  68. info = drm_format_info(mode_cmd->pixel_format);
  69. if (!info || !info->depth) {
  70. struct drm_format_name_buf format_name;
  71. DRM_DEBUG_KMS("non-RGB pixel format %s\n",
  72. drm_get_format_name(mode_cmd->pixel_format,
  73. &format_name));
  74. fb->depth = 0;
  75. fb->bits_per_pixel = 0;
  76. } else {
  77. fb->depth = info->depth;
  78. fb->bits_per_pixel = info->cpp[0] * 8;
  79. }
  80. fb->width = mode_cmd->width;
  81. fb->height = mode_cmd->height;
  82. for (i = 0; i < 4; i++) {
  83. fb->pitches[i] = mode_cmd->pitches[i];
  84. fb->offsets[i] = mode_cmd->offsets[i];
  85. fb->modifier[i] = mode_cmd->modifier[i];
  86. }
  87. fb->pixel_format = mode_cmd->pixel_format;
  88. fb->flags = mode_cmd->flags;
  89. }
  90. EXPORT_SYMBOL(drm_helper_mode_fill_fb_struct);
  91. /*
  92. * This is the minimal list of formats that seem to be safe for modeset use
  93. * with all current DRM drivers. Most hardware can actually support more
  94. * formats than this and drivers may specify a more accurate list when
  95. * creating the primary plane. However drivers that still call
  96. * drm_plane_init() will use this minimal format list as the default.
  97. */
  98. static const uint32_t safe_modeset_formats[] = {
  99. DRM_FORMAT_XRGB8888,
  100. DRM_FORMAT_ARGB8888,
  101. };
  102. static struct drm_plane *create_primary_plane(struct drm_device *dev)
  103. {
  104. struct drm_plane *primary;
  105. int ret;
  106. primary = kzalloc(sizeof(*primary), GFP_KERNEL);
  107. if (primary == NULL) {
  108. DRM_DEBUG_KMS("Failed to allocate primary plane\n");
  109. return NULL;
  110. }
  111. /*
  112. * Remove the format_default field from drm_plane when dropping
  113. * this helper.
  114. */
  115. primary->format_default = true;
  116. /* possible_crtc's will be filled in later by crtc_init */
  117. ret = drm_universal_plane_init(dev, primary, 0,
  118. &drm_primary_helper_funcs,
  119. safe_modeset_formats,
  120. ARRAY_SIZE(safe_modeset_formats),
  121. DRM_PLANE_TYPE_PRIMARY, NULL);
  122. if (ret) {
  123. kfree(primary);
  124. primary = NULL;
  125. }
  126. return primary;
  127. }
  128. /**
  129. * drm_crtc_init - Legacy CRTC initialization function
  130. * @dev: DRM device
  131. * @crtc: CRTC object to init
  132. * @funcs: callbacks for the new CRTC
  133. *
  134. * Initialize a CRTC object with a default helper-provided primary plane and no
  135. * cursor plane.
  136. *
  137. * Returns:
  138. * Zero on success, error code on failure.
  139. */
  140. int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
  141. const struct drm_crtc_funcs *funcs)
  142. {
  143. struct drm_plane *primary;
  144. primary = create_primary_plane(dev);
  145. return drm_crtc_init_with_planes(dev, crtc, primary, NULL, funcs,
  146. NULL);
  147. }
  148. EXPORT_SYMBOL(drm_crtc_init);