diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index 33181be97151e65db4384a29d2df9a88fac65162..b1029e292e5c585fea7dd578aea4d635536ff8ad 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -113,6 +113,9 @@ a hardware-specific ioctl to allocate suitable buffer objects. Plane Abstraction ================= +.. kernel-doc:: drivers/gpu/drm/drm_plane.c + :doc: overview + Plane Functions Reference ------------------------- @@ -189,50 +192,6 @@ allocated and zeroed by the driver, possibly as part of a larger structure, and registered with a call to :c:func:`drm_crtc_init()` with a pointer to CRTC functions. -Planes (:c:type:`struct drm_plane `) ------------------------------------------------ - -A plane represents an image source that can be blended with or overlayed -on top of a CRTC during the scanout process. Planes are associated with -a frame buffer to crop a portion of the image memory (source) and -optionally scale it to a destination size. The result is then blended -with or overlayed on top of a CRTC. - -The DRM core recognizes three types of planes: - -- DRM_PLANE_TYPE_PRIMARY represents a "main" plane for a CRTC. - Primary planes are the planes operated upon by CRTC modesetting and - flipping operations described in the page_flip hook in - :c:type:`struct drm_crtc_funcs `. -- DRM_PLANE_TYPE_CURSOR represents a "cursor" plane for a CRTC. - Cursor planes are the planes operated upon by the - DRM_IOCTL_MODE_CURSOR and DRM_IOCTL_MODE_CURSOR2 ioctls. -- DRM_PLANE_TYPE_OVERLAY represents all non-primary, non-cursor - planes. Some drivers refer to these types of planes as "sprites" - internally. - -For compatibility with legacy userspace, only overlay planes are made -available to userspace by default. Userspace clients may set the -DRM_CLIENT_CAP_UNIVERSAL_PLANES client capability bit to indicate -that they wish to receive a universal plane list containing all plane -types. - -Plane Initialization -~~~~~~~~~~~~~~~~~~~~ - -To create a plane, a KMS drivers allocates and zeroes an instances of -:c:type:`struct drm_plane ` (possibly as part of a -larger structure) and registers it with a call to -:c:func:`drm_universal_plane_init()`. The function takes a -bitmask of the CRTCs that can be associated with the plane, a pointer to -the plane functions, a list of format supported formats, and the type of -plane (primary, cursor, or overlay) being initialized. - -Cursor and overlay planes are optional. All drivers should provide one -primary plane per CRTC (although this requirement may change in the -future); drivers that do not wish to provide special handling for -primary planes may make use of the helper functions described in ? to -create and register a primary plane with standard capabilities. Cleanup ------- diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index deefb24649b2aabb6f8bfe3d3a01db5d4008a7c3..a1a02cdd8883593068fd06b7775b4049523007d2 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -151,7 +151,11 @@ static void drm_crtc_unregister_all(struct drm_device *dev) * @funcs: callbacks for the new CRTC * @name: printf style format string for the CRTC name, or NULL for default name * - * Inits a new object created as base part of a driver crtc object. + * Inits a new object created as base part of a driver crtc object. Drivers + * should use this function instead of drm_crtc_init(), which is only provided + * for backwards compatibility with drivers which do not yet support universal + * planes). For really simple hardware which has only 1 plane look at + * drm_simple_display_pipe_init() instead. * * Returns: * Zero on success, error code on failure. diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 9003b5f835cff77ec736c7afecfb2fe3654b4d58..c17c9c2a342e34c0da30f151d56d6ce5837ef366 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -25,6 +25,28 @@ #include "drm_crtc_internal.h" +/** + * DOC: overview + * + * A plane represents an image source that can be blended with or overlayed on + * top of a CRTC during the scanout process. Planes take their input data from a + * &drm_framebuffer object. The plane itself specifies the cropping and scaling + * of that image, and where it is placed on the visible are of a display + * pipeline, represented by &drm_crtc. A plane can also have additional + * properties that specify how the pixels are positioned and blended, like + * rotation or Z-position. All these properties are stored in &drm_plane_state. + * + * To create a plane, a KMS drivers allocates and zeroes an instances of + * struct &drm_plane (possibly as part of a larger structure) and registers it + * with a call to drm_universal_plane_init(). + * + * Cursor and overlay planes are optional. All drivers should provide one + * primary plane per CRTC to avoid surprising userspace too much. See enum + * &drm_plane_type for a more in-depth discussion of these special uapi-relevant + * plane types. Special planes are associated with their CRTC by calling + * drm_crtc_init_with_planes(). + */ + static unsigned int drm_num_planes(struct drm_device *dev) { unsigned int num = 0; @@ -303,19 +325,6 @@ int drm_mode_plane_set_obj_prop(struct drm_plane *plane, } EXPORT_SYMBOL(drm_mode_plane_set_obj_prop); -/** - * drm_mode_getplane_res - enumerate all plane resources - * @dev: DRM device - * @data: ioctl data - * @file_priv: DRM file info - * - * Construct a list of plane ids to return to the user. - * - * Called by the user via ioctl. - * - * Returns: - * Zero on success, negative errno on failure. - */ int drm_mode_getplane_res(struct drm_device *dev, void *data, struct drm_file *file_priv) { @@ -364,19 +373,6 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data, return 0; } -/** - * drm_mode_getplane - get plane configuration - * @dev: DRM device - * @data: ioctl data - * @file_priv: DRM file info - * - * Construct a plane configuration structure to return to the user. - * - * Called by the user via ioctl. - * - * Returns: - * Zero on success, negative errno on failure. - */ int drm_mode_getplane(struct drm_device *dev, void *data, struct drm_file *file_priv) { @@ -425,15 +421,6 @@ int drm_mode_getplane(struct drm_device *dev, void *data, return 0; } -/** - * drm_plane_check_pixel_format - Check if the plane supports the pixel format - * @plane: plane to check for format support - * @format: the pixel format - * - * Returns: - * Zero of @plane has @format in its list of supported pixel formats, -EINVAL - * otherwise. - */ int drm_plane_check_pixel_format(const struct drm_plane *plane, u32 format) { unsigned int i; @@ -552,19 +539,6 @@ static int setplane_internal(struct drm_plane *plane, return ret; } -/** - * drm_mode_setplane - configure a plane's configuration - * @dev: DRM device - * @data: ioctl data* - * @file_priv: DRM file info - * - * Set plane configuration, including placement, fb, scaling, and other factors. - * Or pass a NULL fb to disable (planes may be disabled without providing a - * valid crtc). - * - * Returns: - * Zero on success, negative errno on failure. - */ int drm_mode_setplane(struct drm_device *dev, void *data, struct drm_file *file_priv) { @@ -614,25 +588,6 @@ int drm_mode_setplane(struct drm_device *dev, void *data, plane_req->src_w, plane_req->src_h); } -/** - * drm_mode_cursor_universal - translate legacy cursor ioctl call into a - * universal plane handler call - * @crtc: crtc to update cursor for - * @req: data pointer for the ioctl - * @file_priv: drm file for the ioctl call - * - * Legacy cursor ioctl's work directly with driver buffer handles. To - * translate legacy ioctl calls into universal plane handler calls, we need to - * wrap the native buffer handle in a drm_framebuffer. - * - * Note that we assume any handle passed to the legacy ioctls was a 32-bit ARGB - * buffer with a pitch of 4*width; the universal plane interface should be used - * directly in cases where the hardware can support other buffer settings and - * userspace wants to make use of these capabilities. - * - * Returns: - * Zero on success, negative errno on failure. - */ static int drm_mode_cursor_universal(struct drm_crtc *crtc, struct drm_mode_cursor2 *req, struct drm_file *file_priv) @@ -768,19 +723,6 @@ static int drm_mode_cursor_common(struct drm_device *dev, } -/** - * drm_mode_cursor_ioctl - set CRTC's cursor configuration - * @dev: drm device for the ioctl - * @data: data pointer for the ioctl - * @file_priv: drm file for the ioctl call - * - * Set the cursor configuration based on user request. - * - * Called by the user via ioctl. - * - * Returns: - * Zero on success, negative errno on failure. - */ int drm_mode_cursor_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { @@ -793,20 +735,10 @@ int drm_mode_cursor_ioctl(struct drm_device *dev, return drm_mode_cursor_common(dev, &new_req, file_priv); } -/** - * drm_mode_cursor2_ioctl - set CRTC's cursor configuration - * @dev: drm device for the ioctl - * @data: data pointer for the ioctl - * @file_priv: drm file for the ioctl call - * +/* * Set the cursor configuration based on user request. This implements the 2nd * version of the cursor ioctl, which allows userspace to additionally specify * the hotspot of the pointer. - * - * Called by the user via ioctl. - * - * Returns: - * Zero on success, negative errno on failure. */ int drm_mode_cursor2_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -816,24 +748,6 @@ int drm_mode_cursor2_ioctl(struct drm_device *dev, return drm_mode_cursor_common(dev, req, file_priv); } -/** - * drm_mode_page_flip_ioctl - schedule an asynchronous fb update - * @dev: DRM device - * @data: ioctl data - * @file_priv: DRM file info - * - * This schedules an asynchronous update on a given CRTC, called page flip. - * Optionally a drm event is generated to signal the completion of the event. - * Generic drivers cannot assume that a pageflip with changed framebuffer - * properties (including driver specific metadata like tiling layout) will work, - * but some drivers support e.g. pixel format changes through the pageflip - * ioctl. - * - * Called by the user via ioctl. - * - * Returns: - * Zero on success, negative errno on failure. - */ int drm_mode_page_flip_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 1407715736a599a0f4c41769c5d29ae04a4dbe08..256219bfd07b8cf65cc402822d0a588b9457c5a2 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -319,10 +319,48 @@ struct drm_plane_funcs { void (*early_unregister)(struct drm_plane *plane); }; +/** + * enum drm_plane_type - uapi plane type enumeration + * + * For historical reasons not all planes are made the same. This enumeration is + * used to tell the different types of planes apart to implement the different + * uapi semantics for them. For userspace which is universal plane aware and + * which is using that atomic IOCTL there's no difference between these planes + * (beyong what the driver and hardware can support of course). + * + * For compatibility with legacy userspace, only overlay planes are made + * available to userspace by default. Userspace clients may set the + * DRM_CLIENT_CAP_UNIVERSAL_PLANES client capability bit to indicate that they + * wish to receive a universal plane list containing all plane types. See also + * drm_for_each_legacy_plane(). + */ enum drm_plane_type { - DRM_PLANE_TYPE_OVERLAY, + /** + * @DRM_PLANE_TYPE_PRIMARY: + * + * Primary planes represent a "main" plane for a CRTC. Primary planes + * are the planes operated upon by CRTC modesetting and flipping + * operations described in the page_flip and set_config hooks in struct + * &drm_crtc_funcs. + */ DRM_PLANE_TYPE_PRIMARY, + + /** + * @DRM_PLANE_TYPE_CURSOR: + * + * Cursor planes represent a "cursor" plane for a CRTC. Cursor planes + * are the planes operated upon by the DRM_IOCTL_MODE_CURSOR and + * DRM_IOCTL_MODE_CURSOR2 IOCTLs. + */ DRM_PLANE_TYPE_CURSOR, + + /** + * @DRM_PLANE_TYPE_OVERLAY: + * + * Overlay planes represent all non-primary, non-cursor planes. Some + * drivers refer to these types of planes as "sprites" internally. + */ + DRM_PLANE_TYPE_OVERLAY, }; @@ -458,11 +496,26 @@ static inline struct drm_plane *drm_plane_find(struct drm_device *dev, list_for_each_entry((plane), &(dev)->mode_config.plane_list, head) \ for_each_if ((plane_mask) & (1 << drm_plane_index(plane))) -/* Plane list iterator for legacy (overlay only) planes. */ +/** + * drm_for_each_legacy_plane - iterate over all planes for legacy userspace + * @plane: the loop cursor + * @dev: the DRM device + * + * Iterate over all legacy planes of @dev, excluding primary and cursor planes. + * This is useful for implementing userspace apis when userspace is not + * universal plane aware. See also enum &drm_plane_type. + */ #define drm_for_each_legacy_plane(plane, dev) \ list_for_each_entry(plane, &(dev)->mode_config.plane_list, head) \ for_each_if (plane->type == DRM_PLANE_TYPE_OVERLAY) +/** + * drm_for_each_plane - iterate over all planes + * @plane: the loop cursor + * @dev: the DRM device + * + * Iterate over all planes of @dev, include primary and cursor planes. + */ #define drm_for_each_plane(plane, dev) \ list_for_each_entry(plane, &(dev)->mode_config.plane_list, head)