2016-08-15 22:07:02 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2016 Intel Corporation
|
|
|
|
*
|
|
|
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
|
|
|
* documentation for any purpose is hereby granted without fee, provided that
|
|
|
|
* the above copyright notice appear in all copies and that both that copyright
|
|
|
|
* notice and this permission notice appear in supporting documentation, and
|
|
|
|
* that the name of the copyright holders not be used in advertising or
|
|
|
|
* publicity pertaining to distribution of the software without specific,
|
|
|
|
* written prior permission. The copyright holders make no representations
|
|
|
|
* about the suitability of this software for any purpose. It is provided "as
|
|
|
|
* is" without express or implied warranty.
|
|
|
|
*
|
|
|
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
|
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
|
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
|
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
|
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
|
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
|
|
|
* OF THIS SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __DRM_MODESET_H__
|
|
|
|
#define __DRM_MODESET_H__
|
|
|
|
|
|
|
|
#include <linux/kref.h>
|
drm: Add drm_object lease infrastructure [v5]
This provides new data structures to hold "lease" information about
drm mode setting objects, and provides for creating new drm_masters
which have access to a subset of the available drm resources.
An 'owner' is a drm_master which is not leasing the objects from
another drm_master, and hence 'owns' them.
A 'lessee' is a drm_master which is leasing objects from some other
drm_master. Each lessee holds the set of objects which it is leasing
from the lessor.
A 'lessor' is a drm_master which is leasing objects to another
drm_master. This is the same as the owner in the current code.
The set of objects any drm_master 'controls' is limited to the set of
objects it leases (for lessees) or all objects (for owners).
Objects not controlled by a drm_master cannot be modified through the
various state manipulating ioctls, and any state reported back to user
space will be edited to make them appear idle and/or unusable. For
instance, connectors always report 'disconnected', while encoders
report no possible crtcs or clones.
The full list of lessees leasing objects from an owner (either
directly, or indirectly through another lessee), can be searched from
an idr in the drm_master of the owner.
Changes for v2 as suggested by Daniel Vetter <daniel.vetter@ffwll.ch>:
* Sub-leasing has been disabled.
* BUG_ON for lock checking replaced with lockdep_assert_held
* 'change' ioctl has been removed.
* Leased objects can always be controlled by the lessor; the
'mask_lease' flag has been removed
* Checking for leased status has been simplified, replacing
the drm_lease_check function with drm_lease_held.
Changes in v3, some suggested by Dave Airlie <airlied@gmail.com>
* Add revocation. This allows leases to be effectively revoked by
removing all of the objects they have access to. The lease itself
hangs around as it's hanging off a file.
* Free the leases IDR when the master is destroyed
* _drm_lease_held should look at lessees, not lessor
* Allow non-master files to check for lease status
Changes in v4, suggested by Dave Airlie <airlied@gmail.com>
* Formatting and whitespace changes
Changes in v5 (airlied)
* check DRIVER_MODESET before lease destroy call
* check DRIVER_MODESET for lease revoke (Chris)
* Use idr_mutex uniformly for all lease elements of struct drm_master. (Keith)
Signed-off-by: Keith Packard <keithp@keithp.com>
2017-03-15 13:26:41 +08:00
|
|
|
#include <drm/drm_lease.h>
|
2016-08-15 22:07:02 +08:00
|
|
|
struct drm_object_properties;
|
2016-08-13 04:48:50 +08:00
|
|
|
struct drm_property;
|
2016-09-01 00:09:05 +08:00
|
|
|
struct drm_device;
|
2017-03-15 14:25:07 +08:00
|
|
|
struct drm_file;
|
2016-08-15 22:07:02 +08:00
|
|
|
|
2016-08-29 16:27:53 +08:00
|
|
|
/**
|
|
|
|
* struct drm_mode_object - base structure for modeset objects
|
|
|
|
* @id: userspace visible identifier
|
|
|
|
* @type: type of the object, one of DRM_MODE_OBJECT\_\*
|
|
|
|
* @properties: properties attached to this object, including values
|
|
|
|
* @refcount: reference count for objects which with dynamic lifetime
|
|
|
|
* @free_cb: free function callback, only set for objects with dynamic lifetime
|
|
|
|
*
|
|
|
|
* Base structure for modeset objects visible to userspace. Objects can be
|
|
|
|
* looked up using drm_mode_object_find(). Besides basic uapi interface
|
|
|
|
* properties like @id and @type it provides two services:
|
|
|
|
*
|
|
|
|
* - It tracks attached properties and their values. This is used by &drm_crtc,
|
|
|
|
* &drm_plane and &drm_connector. Properties are attached by calling
|
|
|
|
* drm_object_attach_property() before the object is visible to userspace.
|
|
|
|
*
|
|
|
|
* - For objects with dynamic lifetimes (as indicated by a non-NULL @free_cb) it
|
2017-02-28 22:46:38 +08:00
|
|
|
* provides reference counting through drm_mode_object_get() and
|
|
|
|
* drm_mode_object_put(). This is used by &drm_framebuffer, &drm_connector
|
|
|
|
* and &drm_property_blob. These objects provide specialized reference
|
|
|
|
* counting wrappers.
|
2016-08-29 16:27:53 +08:00
|
|
|
*/
|
2016-08-15 22:07:02 +08:00
|
|
|
struct drm_mode_object {
|
|
|
|
uint32_t id;
|
|
|
|
uint32_t type;
|
|
|
|
struct drm_object_properties *properties;
|
|
|
|
struct kref refcount;
|
|
|
|
void (*free_cb)(struct kref *kref);
|
|
|
|
};
|
|
|
|
|
2016-08-13 04:48:50 +08:00
|
|
|
#define DRM_OBJECT_MAX_PROPERTY 24
|
2016-08-29 16:27:53 +08:00
|
|
|
/**
|
|
|
|
* struct drm_object_properties - property tracking for &drm_mode_object
|
|
|
|
*/
|
2016-08-13 04:48:50 +08:00
|
|
|
struct drm_object_properties {
|
2016-08-29 16:27:53 +08:00
|
|
|
/**
|
|
|
|
* @count: number of valid properties, must be less than or equal to
|
|
|
|
* DRM_OBJECT_MAX_PROPERTY.
|
|
|
|
*/
|
|
|
|
|
2016-08-29 16:27:52 +08:00
|
|
|
int count;
|
2016-08-29 16:27:53 +08:00
|
|
|
/**
|
|
|
|
* @properties: Array of pointers to &drm_property.
|
|
|
|
*
|
|
|
|
* NOTE: if we ever start dynamically destroying properties (ie.
|
2016-08-13 04:48:50 +08:00
|
|
|
* not at drm_mode_config_cleanup() time), then we'd have to do
|
|
|
|
* a better job of detaching property from mode objects to avoid
|
|
|
|
* dangling property pointers:
|
|
|
|
*/
|
|
|
|
struct drm_property *properties[DRM_OBJECT_MAX_PROPERTY];
|
2016-08-29 16:27:53 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @values: Array to store the property values, matching @properties. Do
|
|
|
|
* not read/write values directly, but use
|
|
|
|
* drm_object_property_get_value() and drm_object_property_set_value().
|
|
|
|
*
|
|
|
|
* Note that atomic drivers do not store mutable properties in this
|
|
|
|
* array, but only the decoded values in the corresponding state
|
2017-01-25 14:26:45 +08:00
|
|
|
* structure. The decoding is done using the &drm_crtc.atomic_get_property and
|
|
|
|
* &drm_crtc.atomic_set_property hooks for &struct drm_crtc. For
|
|
|
|
* &struct drm_plane the hooks are &drm_plane_funcs.atomic_get_property and
|
|
|
|
* &drm_plane_funcs.atomic_set_property. And for &struct drm_connector
|
|
|
|
* the hooks are &drm_connector_funcs.atomic_get_property and
|
|
|
|
* &drm_connector_funcs.atomic_set_property .
|
|
|
|
*
|
|
|
|
* Hence atomic drivers should not use drm_object_property_set_value()
|
|
|
|
* and drm_object_property_get_value() on mutable objects, i.e. those
|
2016-08-29 16:27:53 +08:00
|
|
|
* without the DRM_MODE_PROP_IMMUTABLE flag set.
|
2016-08-13 04:48:50 +08:00
|
|
|
*/
|
|
|
|
uint64_t values[DRM_OBJECT_MAX_PROPERTY];
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Avoid boilerplate. I'm tired of typing. */
|
|
|
|
#define DRM_ENUM_NAME_FN(fnname, list) \
|
|
|
|
const char *fnname(int val) \
|
|
|
|
{ \
|
|
|
|
int i; \
|
|
|
|
for (i = 0; i < ARRAY_SIZE(list); i++) { \
|
|
|
|
if (list[i].type == val) \
|
|
|
|
return list[i].name; \
|
|
|
|
} \
|
|
|
|
return "(unknown)"; \
|
|
|
|
}
|
|
|
|
|
2016-08-15 22:07:02 +08:00
|
|
|
struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
|
2017-03-15 14:25:07 +08:00
|
|
|
struct drm_file *file_priv,
|
2016-08-15 22:07:02 +08:00
|
|
|
uint32_t id, uint32_t type);
|
2017-02-28 22:46:38 +08:00
|
|
|
void drm_mode_object_get(struct drm_mode_object *obj);
|
|
|
|
void drm_mode_object_put(struct drm_mode_object *obj);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* drm_mode_object_reference - acquire a mode object reference
|
|
|
|
* @obj: DRM mode object
|
|
|
|
*
|
|
|
|
* This is a compatibility alias for drm_mode_object_get() and should not be
|
|
|
|
* used by new code.
|
|
|
|
*/
|
|
|
|
static inline void drm_mode_object_reference(struct drm_mode_object *obj)
|
|
|
|
{
|
|
|
|
drm_mode_object_get(obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* drm_mode_object_unreference - release a mode object reference
|
|
|
|
* @obj: DRM mode object
|
|
|
|
*
|
|
|
|
* This is a compatibility alias for drm_mode_object_put() and should not be
|
|
|
|
* used by new code.
|
|
|
|
*/
|
|
|
|
static inline void drm_mode_object_unreference(struct drm_mode_object *obj)
|
|
|
|
{
|
|
|
|
drm_mode_object_put(obj);
|
|
|
|
}
|
2016-08-15 22:07:02 +08:00
|
|
|
|
2016-08-29 16:27:51 +08:00
|
|
|
int drm_object_property_set_value(struct drm_mode_object *obj,
|
|
|
|
struct drm_property *property,
|
|
|
|
uint64_t val);
|
|
|
|
int drm_object_property_get_value(struct drm_mode_object *obj,
|
|
|
|
struct drm_property *property,
|
|
|
|
uint64_t *value);
|
|
|
|
|
|
|
|
void drm_object_attach_property(struct drm_mode_object *obj,
|
|
|
|
struct drm_property *property,
|
|
|
|
uint64_t init_val);
|
2017-03-17 08:56:28 +08:00
|
|
|
|
|
|
|
bool drm_mode_object_lease_required(uint32_t type);
|
2016-08-15 22:07:02 +08:00
|
|
|
#endif
|