drm: Extract drm_plane.[hc]

Just pure code movement, cleanup and polish will happen in later
patches.

v2: Don't forget all the ioctl! To extract those cleanly I decided to
put check_src_coords into drm_framebuffer.c (and give it a
drm_framebuffer_ prefix), since that just checks framebuffer
constraints.

v3: rebase over PAGE_FLIP_TARGET.

Reviewed-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

[seanpaul]
This patch as posted on the list was rebased on:

commit 6f00975c619064a18c23fd3aced325ae165a73b9
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date:   Sat Aug 20 12:22:11 2016 +0200

    drm: Reject page_flip for !DRIVER_MODESET

so as a result of moving the page_flip ioctl, this fix has
been rolled into this patch.

Signed-off-by: Sean Paul <seanpaul@chromium.org>
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 35b13fc..9375e5c 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -44,6 +44,7 @@
 #include <drm/drm_property.h>
 #include <drm/drm_bridge.h>
 #include <drm/drm_edid.h>
+#include <drm/drm_plane.h>
 
 struct drm_device;
 struct drm_mode_set;
@@ -657,525 +658,6 @@
 };
 
 /**
- * struct drm_plane_state - mutable plane state
- * @plane: backpointer to the plane
- * @crtc: currently bound CRTC, NULL if disabled
- * @fb: currently bound framebuffer
- * @fence: optional fence to wait for before scanning out @fb
- * @crtc_x: left position of visible portion of plane on crtc
- * @crtc_y: upper position of visible portion of plane on crtc
- * @crtc_w: width of visible portion of plane on crtc
- * @crtc_h: height of visible portion of plane on crtc
- * @src_x: left position of visible portion of plane within
- *	plane (in 16.16)
- * @src_y: upper position of visible portion of plane within
- *	plane (in 16.16)
- * @src_w: width of visible portion of plane (in 16.16)
- * @src_h: height of visible portion of plane (in 16.16)
- * @rotation: rotation of the plane
- * @zpos: priority of the given plane on crtc (optional)
- * @normalized_zpos: normalized value of zpos: unique, range from 0 to N-1
- *	where N is the number of active planes for given crtc
- * @src: clipped source coordinates of the plane (in 16.16)
- * @dst: clipped destination coordinates of the plane
- * @visible: visibility of the plane
- * @state: backpointer to global drm_atomic_state
- */
-struct drm_plane_state {
-	struct drm_plane *plane;
-
-	struct drm_crtc *crtc;   /* do not write directly, use drm_atomic_set_crtc_for_plane() */
-	struct drm_framebuffer *fb;  /* do not write directly, use drm_atomic_set_fb_for_plane() */
-	struct fence *fence;
-
-	/* Signed dest location allows it to be partially off screen */
-	int32_t crtc_x, crtc_y;
-	uint32_t crtc_w, crtc_h;
-
-	/* Source values are 16.16 fixed point */
-	uint32_t src_x, src_y;
-	uint32_t src_h, src_w;
-
-	/* Plane rotation */
-	unsigned int rotation;
-
-	/* Plane zpos */
-	unsigned int zpos;
-	unsigned int normalized_zpos;
-
-	/* Clipped coordinates */
-	struct drm_rect src, dst;
-
-	/*
-	 * Is the plane actually visible? Can be false even
-	 * if fb!=NULL and crtc!=NULL, due to clipping.
-	 */
-	bool visible;
-
-	struct drm_atomic_state *state;
-};
-
-
-/**
- * struct drm_plane_funcs - driver plane control functions
- */
-struct drm_plane_funcs {
-	/**
-	 * @update_plane:
-	 *
-	 * This is the legacy entry point to enable and configure the plane for
-	 * the given CRTC and framebuffer. It is never called to disable the
-	 * plane, i.e. the passed-in crtc and fb paramters are never NULL.
-	 *
-	 * The source rectangle in frame buffer memory coordinates is given by
-	 * the src_x, src_y, src_w and src_h parameters (as 16.16 fixed point
-	 * values). Devices that don't support subpixel plane coordinates can
-	 * ignore the fractional part.
-	 *
-	 * The destination rectangle in CRTC coordinates is given by the
-	 * crtc_x, crtc_y, crtc_w and crtc_h parameters (as integer values).
-	 * Devices scale the source rectangle to the destination rectangle. If
-	 * scaling is not supported, and the source rectangle size doesn't match
-	 * the destination rectangle size, the driver must return a
-	 * -<errorname>EINVAL</errorname> error.
-	 *
-	 * Drivers implementing atomic modeset should use
-	 * drm_atomic_helper_update_plane() to implement this hook.
-	 *
-	 * RETURNS:
-	 *
-	 * 0 on success or a negative error code on failure.
-	 */
-	int (*update_plane)(struct drm_plane *plane,
-			    struct drm_crtc *crtc, struct drm_framebuffer *fb,
-			    int crtc_x, int crtc_y,
-			    unsigned int crtc_w, unsigned int crtc_h,
-			    uint32_t src_x, uint32_t src_y,
-			    uint32_t src_w, uint32_t src_h);
-
-	/**
-	 * @disable_plane:
-	 *
-	 * This is the legacy entry point to disable the plane. The DRM core
-	 * calls this method in response to a DRM_IOCTL_MODE_SETPLANE IOCTL call
-	 * with the frame buffer ID set to 0.  Disabled planes must not be
-	 * processed by the CRTC.
-	 *
-	 * Drivers implementing atomic modeset should use
-	 * drm_atomic_helper_disable_plane() to implement this hook.
-	 *
-	 * RETURNS:
-	 *
-	 * 0 on success or a negative error code on failure.
-	 */
-	int (*disable_plane)(struct drm_plane *plane);
-
-	/**
-	 * @destroy:
-	 *
-	 * Clean up plane resources. This is only called at driver unload time
-	 * through drm_mode_config_cleanup() since a plane cannot be hotplugged
-	 * in DRM.
-	 */
-	void (*destroy)(struct drm_plane *plane);
-
-	/**
-	 * @reset:
-	 *
-	 * Reset plane hardware and software state to off. This function isn't
-	 * called by the core directly, only through drm_mode_config_reset().
-	 * It's not a helper hook only for historical reasons.
-	 *
-	 * Atomic drivers can use drm_atomic_helper_plane_reset() to reset
-	 * atomic state using this hook.
-	 */
-	void (*reset)(struct drm_plane *plane);
-
-	/**
-	 * @set_property:
-	 *
-	 * This is the legacy entry point to update a property attached to the
-	 * plane.
-	 *
-	 * Drivers implementing atomic modeset should use
-	 * drm_atomic_helper_plane_set_property() to implement this hook.
-	 *
-	 * This callback is optional if the driver does not support any legacy
-	 * driver-private properties.
-	 *
-	 * RETURNS:
-	 *
-	 * 0 on success or a negative error code on failure.
-	 */
-	int (*set_property)(struct drm_plane *plane,
-			    struct drm_property *property, uint64_t val);
-
-	/**
-	 * @atomic_duplicate_state:
-	 *
-	 * Duplicate the current atomic state for this plane and return it.
-	 * The core and helpers gurantee that any atomic state duplicated with
-	 * this hook and still owned by the caller (i.e. not transferred to the
-	 * driver by calling ->atomic_commit() from struct
-	 * &drm_mode_config_funcs) will be cleaned up by calling the
-	 * @atomic_destroy_state hook in this structure.
-	 *
-	 * Atomic drivers which don't subclass struct &drm_plane_state should use
-	 * drm_atomic_helper_plane_duplicate_state(). Drivers that subclass the
-	 * state structure to extend it with driver-private state should use
-	 * __drm_atomic_helper_plane_duplicate_state() to make sure shared state is
-	 * duplicated in a consistent fashion across drivers.
-	 *
-	 * It is an error to call this hook before plane->state has been
-	 * initialized correctly.
-	 *
-	 * NOTE:
-	 *
-	 * If the duplicate state references refcounted resources this hook must
-	 * acquire a reference for each of them. The driver must release these
-	 * references again in @atomic_destroy_state.
-	 *
-	 * RETURNS:
-	 *
-	 * Duplicated atomic state or NULL when the allocation failed.
-	 */
-	struct drm_plane_state *(*atomic_duplicate_state)(struct drm_plane *plane);
-
-	/**
-	 * @atomic_destroy_state:
-	 *
-	 * Destroy a state duplicated with @atomic_duplicate_state and release
-	 * or unreference all resources it references
-	 */
-	void (*atomic_destroy_state)(struct drm_plane *plane,
-				     struct drm_plane_state *state);
-
-	/**
-	 * @atomic_set_property:
-	 *
-	 * Decode a driver-private property value and store the decoded value
-	 * into the passed-in state structure. Since the atomic core decodes all
-	 * standardized properties (even for extensions beyond the core set of
-	 * properties which might not be implemented by all drivers) this
-	 * requires drivers to subclass the state structure.
-	 *
-	 * Such driver-private properties should really only be implemented for
-	 * truly hardware/vendor specific state. Instead it is preferred to
-	 * standardize atomic extension and decode the properties used to expose
-	 * such an extension in the core.
-	 *
-	 * Do not call this function directly, use
-	 * drm_atomic_plane_set_property() instead.
-	 *
-	 * This callback is optional if the driver does not support any
-	 * driver-private atomic properties.
-	 *
-	 * NOTE:
-	 *
-	 * This function is called in the state assembly phase of atomic
-	 * modesets, which can be aborted for any reason (including on
-	 * userspace's request to just check whether a configuration would be
-	 * possible). Drivers MUST NOT touch any persistent state (hardware or
-	 * software) or data structures except the passed in @state parameter.
-	 *
-	 * Also since userspace controls in which order properties are set this
-	 * function must not do any input validation (since the state update is
-	 * incomplete and hence likely inconsistent). Instead any such input
-	 * validation must be done in the various atomic_check callbacks.
-	 *
-	 * RETURNS:
-	 *
-	 * 0 if the property has been found, -EINVAL if the property isn't
-	 * implemented by the driver (which shouldn't ever happen, the core only
-	 * asks for properties attached to this plane). No other validation is
-	 * allowed by the driver. The core already checks that the property
-	 * value is within the range (integer, valid enum value, ...) the driver
-	 * set when registering the property.
-	 */
-	int (*atomic_set_property)(struct drm_plane *plane,
-				   struct drm_plane_state *state,
-				   struct drm_property *property,
-				   uint64_t val);
-
-	/**
-	 * @atomic_get_property:
-	 *
-	 * Reads out the decoded driver-private property. This is used to
-	 * implement the GETPLANE IOCTL.
-	 *
-	 * Do not call this function directly, use
-	 * drm_atomic_plane_get_property() instead.
-	 *
-	 * This callback is optional if the driver does not support any
-	 * driver-private atomic properties.
-	 *
-	 * RETURNS:
-	 *
-	 * 0 on success, -EINVAL if the property isn't implemented by the
-	 * driver (which should never happen, the core only asks for
-	 * properties attached to this plane).
-	 */
-	int (*atomic_get_property)(struct drm_plane *plane,
-				   const struct drm_plane_state *state,
-				   struct drm_property *property,
-				   uint64_t *val);
-	/**
-	 * @late_register:
-	 *
-	 * This optional hook can be used to register additional userspace
-	 * interfaces attached to the plane like debugfs interfaces.
-	 * It is called late in the driver load sequence from drm_dev_register().
-	 * Everything added from this callback should be unregistered in
-	 * the early_unregister callback.
-	 *
-	 * Returns:
-	 *
-	 * 0 on success, or a negative error code on failure.
-	 */
-	int (*late_register)(struct drm_plane *plane);
-
-	/**
-	 * @early_unregister:
-	 *
-	 * This optional hook should be used to unregister the additional
-	 * userspace interfaces attached to the plane from
-	 * late_unregister(). It is called from drm_dev_unregister(),
-	 * early in the driver unload sequence to disable userspace access
-	 * before data structures are torndown.
-	 */
-	void (*early_unregister)(struct drm_plane *plane);
-};
-
-enum drm_plane_type {
-	DRM_PLANE_TYPE_OVERLAY,
-	DRM_PLANE_TYPE_PRIMARY,
-	DRM_PLANE_TYPE_CURSOR,
-};
-
-
-/**
- * struct drm_plane - central DRM plane control structure
- * @dev: DRM device this plane belongs to
- * @head: for list management
- * @name: human readable name, can be overwritten by the driver
- * @base: base mode object
- * @possible_crtcs: pipes this plane can be bound to
- * @format_types: array of formats supported by this plane
- * @format_count: number of formats supported
- * @format_default: driver hasn't supplied supported formats for the plane
- * @crtc: currently bound CRTC
- * @fb: currently bound fb
- * @old_fb: Temporary tracking of the old fb while a modeset is ongoing. Used by
- * 	drm_mode_set_config_internal() to implement correct refcounting.
- * @funcs: helper functions
- * @properties: property tracking for this plane
- * @type: type of plane (overlay, primary, cursor)
- * @state: current atomic state for this plane
- * @zpos_property: zpos property for this plane
- * @helper_private: mid-layer private data
- */
-struct drm_plane {
-	struct drm_device *dev;
-	struct list_head head;
-
-	char *name;
-
-	/**
-	 * @mutex:
-	 *
-	 * Protects modeset plane state, together with the mutex of &drm_crtc
-	 * this plane is linked to (when active, getting actived or getting
-	 * disabled).
-	 */
-	struct drm_modeset_lock mutex;
-
-	struct drm_mode_object base;
-
-	uint32_t possible_crtcs;
-	uint32_t *format_types;
-	unsigned int format_count;
-	bool format_default;
-
-	struct drm_crtc *crtc;
-	struct drm_framebuffer *fb;
-
-	struct drm_framebuffer *old_fb;
-
-	const struct drm_plane_funcs *funcs;
-
-	struct drm_object_properties properties;
-
-	enum drm_plane_type type;
-
-	/**
-	 * @index: Position inside the mode_config.list, can be used as an array
-	 * index. It is invariant over the lifetime of the plane.
-	 */
-	unsigned index;
-
-	const struct drm_plane_helper_funcs *helper_private;
-
-	struct drm_plane_state *state;
-
-	struct drm_property *zpos_property;
-};
-
-/**
- * struct drm_crtc_commit - track modeset commits on a CRTC
- *
- * This structure is used to track pending modeset changes and atomic commit on
- * a per-CRTC basis. Since updating the list should never block this structure
- * is reference counted to allow waiters to safely wait on an event to complete,
- * without holding any locks.
- *
- * It has 3 different events in total to allow a fine-grained synchronization
- * between outstanding updates::
- *
- *	atomic commit thread			hardware
- *
- * 	write new state into hardware	---->	...
- * 	signal hw_done
- * 						switch to new state on next
- * 	...					v/hblank
- *
- *	wait for buffers to show up		...
- *
- *	...					send completion irq
- *						irq handler signals flip_done
- *	cleanup old buffers
- *
- * 	signal cleanup_done
- *
- * 	wait for flip_done		<----
- * 	clean up atomic state
- *
- * The important bit to know is that cleanup_done is the terminal event, but the
- * ordering between flip_done and hw_done is entirely up to the specific driver
- * and modeset state change.
- *
- * For an implementation of how to use this look at
- * drm_atomic_helper_setup_commit() from the atomic helper library.
- */
-struct drm_crtc_commit {
-	/**
-	 * @crtc:
-	 *
-	 * DRM CRTC for this commit.
-	 */
-	struct drm_crtc *crtc;
-
-	/**
-	 * @ref:
-	 *
-	 * Reference count for this structure. Needed to allow blocking on
-	 * completions without the risk of the completion disappearing
-	 * meanwhile.
-	 */
-	struct kref ref;
-
-	/**
-	 * @flip_done:
-	 *
-	 * Will be signaled when the hardware has flipped to the new set of
-	 * buffers. Signals at the same time as when the drm event for this
-	 * commit is sent to userspace, or when an out-fence is singalled. Note
-	 * that for most hardware, in most cases this happens after @hw_done is
-	 * signalled.
-	 */
-	struct completion flip_done;
-
-	/**
-	 * @hw_done:
-	 *
-	 * Will be signalled when all hw register changes for this commit have
-	 * been written out. Especially when disabling a pipe this can be much
-	 * later than than @flip_done, since that can signal already when the
-	 * screen goes black, whereas to fully shut down a pipe more register
-	 * I/O is required.
-	 *
-	 * Note that this does not need to include separately reference-counted
-	 * resources like backing storage buffer pinning, or runtime pm
-	 * management.
-	 */
-	struct completion hw_done;
-
-	/**
-	 * @cleanup_done:
-	 *
-	 * Will be signalled after old buffers have been cleaned up by calling
-	 * drm_atomic_helper_cleanup_planes(). Since this can only happen after
-	 * a vblank wait completed it might be a bit later. This completion is
-	 * useful to throttle updates and avoid hardware updates getting ahead
-	 * of the buffer cleanup too much.
-	 */
-	struct completion cleanup_done;
-
-	/**
-	 * @commit_entry:
-	 *
-	 * Entry on the per-CRTC commit_list. Protected by crtc->commit_lock.
-	 */
-	struct list_head commit_entry;
-
-	/**
-	 * @event:
-	 *
-	 * &drm_pending_vblank_event pointer to clean up private events.
-	 */
-	struct drm_pending_vblank_event *event;
-};
-
-struct __drm_planes_state {
-	struct drm_plane *ptr;
-	struct drm_plane_state *state;
-};
-
-struct __drm_crtcs_state {
-	struct drm_crtc *ptr;
-	struct drm_crtc_state *state;
-	struct drm_crtc_commit *commit;
-};
-
-struct __drm_connnectors_state {
-	struct drm_connector *ptr;
-	struct drm_connector_state *state;
-};
-
-/**
- * struct drm_atomic_state - the global state object for atomic updates
- * @dev: parent DRM device
- * @allow_modeset: allow full modeset
- * @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics
- * @legacy_set_config: Disable conflicting encoders instead of failing with -EINVAL.
- * @planes: pointer to array of structures with per-plane data
- * @crtcs: pointer to array of CRTC pointers
- * @num_connector: size of the @connectors and @connector_states arrays
- * @connectors: pointer to array of structures with per-connector data
- * @acquire_ctx: acquire context for this atomic modeset state update
- */
-struct drm_atomic_state {
-	struct drm_device *dev;
-	bool allow_modeset : 1;
-	bool legacy_cursor_update : 1;
-	bool legacy_set_config : 1;
-	struct __drm_planes_state *planes;
-	struct __drm_crtcs_state *crtcs;
-	int num_connector;
-	struct __drm_connnectors_state *connectors;
-
-	struct drm_modeset_acquire_ctx *acquire_ctx;
-
-	/**
-	 * @commit_work:
-	 *
-	 * Work item which can be used by the driver or helpers to execute the
-	 * commit without blocking.
-	 */
-	struct work_struct commit_work;
-};
-
-
-/**
  * struct drm_mode_set - new values for a CRTC config change
  * @fb: framebuffer to use for new config
  * @crtc: CRTC whose configuration we're about to change
@@ -1825,20 +1307,7 @@
 	struct drm_mode_config_helper_funcs *helper_private;
 };
 
-/**
- * drm_for_each_plane_mask - iterate over planes specified by bitmask
- * @plane: the loop cursor
- * @dev: the DRM device
- * @plane_mask: bitmask of plane indices
- *
- * Iterate over all planes specified by bitmask.
- */
-#define drm_for_each_plane_mask(plane, dev, plane_mask) \
-	list_for_each_entry((plane), &(dev)->mode_config.plane_list, head) \
-		for_each_if ((plane_mask) & (1 << drm_plane_index(plane)))
-
 #define obj_to_crtc(x) container_of(x, struct drm_crtc, base)
-#define obj_to_plane(x) container_of(x, struct drm_plane, base)
 
 extern __printf(6, 7)
 int drm_crtc_init_with_planes(struct drm_device *dev,
@@ -1873,36 +1342,6 @@
 	return 1 << drm_crtc_index(crtc);
 }
 
-extern __printf(8, 9)
-int drm_universal_plane_init(struct drm_device *dev,
-			     struct drm_plane *plane,
-			     unsigned long possible_crtcs,
-			     const struct drm_plane_funcs *funcs,
-			     const uint32_t *formats,
-			     unsigned int format_count,
-			     enum drm_plane_type type,
-			     const char *name, ...);
-extern int drm_plane_init(struct drm_device *dev,
-			  struct drm_plane *plane,
-			  unsigned long possible_crtcs,
-			  const struct drm_plane_funcs *funcs,
-			  const uint32_t *formats, unsigned int format_count,
-			  bool is_primary);
-extern void drm_plane_cleanup(struct drm_plane *plane);
-
-/**
- * drm_plane_index - find the index of a registered plane
- * @plane: plane to find index for
- *
- * Given a registered plane, return the index of that plane within a DRM
- * device's list of planes.
- */
-static inline unsigned int drm_plane_index(struct drm_plane *plane)
-{
-	return plane->index;
-}
-extern struct drm_plane * drm_plane_from_index(struct drm_device *dev, int idx);
-extern void drm_plane_force_disable(struct drm_plane *plane);
 extern void drm_crtc_get_hv_timing(const struct drm_display_mode *mode,
 				   int *hdisplay, int *vdisplay);
 extern int drm_crtc_force_disable(struct drm_crtc *crtc);
@@ -1924,10 +1363,6 @@
 extern void drm_mode_put_tile_group(struct drm_device *dev,
 				   struct drm_tile_group *tg);
 
-extern int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
-				       struct drm_property *property,
-				       uint64_t value);
-
 extern struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
 							      unsigned int supported_rotations);
 extern unsigned int drm_rotation_simplify(unsigned int rotation,
@@ -1945,14 +1380,6 @@
 					     unsigned int zpos);
 
 /* Helpers */
-static inline struct drm_plane *drm_plane_find(struct drm_device *dev,
-		uint32_t id)
-{
-	struct drm_mode_object *mo;
-	mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_PLANE);
-	return mo ? obj_to_plane(mo) : NULL;
-}
-
 static inline struct drm_crtc *drm_crtc_find(struct drm_device *dev,
 	uint32_t id)
 {
@@ -1980,14 +1407,6 @@
 	return clamp_val(val, 0, max);
 }
 
-/* Plane list iterator for legacy (overlay only) planes. */
-#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)
-
-#define drm_for_each_plane(plane, dev) \
-	list_for_each_entry(plane, &(dev)->mode_config.plane_list, head)
-
 #define drm_for_each_crtc(crtc, dev) \
 	list_for_each_entry(crtc, &(dev)->mode_config.crtc_list, head)