mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-29 23:53:32 +00:00
drm/atomic: atomic plane properties
Expose the core plane state as properties, so they can be updated via atomic ioctl. v2: atomic property flag Signed-off-by: Rob Clark <robdclark@gmail.com> Reviewed-by: Sean Paul <seanpaul@chromium.org> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
356af0e154
commit
6b4959f43a
4 changed files with 230 additions and 26 deletions
|
@ -2572,7 +2572,7 @@ void intel_crt_init(struct drm_device *dev)
|
||||||
<td valign="top" >Description/Restrictions</td>
|
<td valign="top" >Description/Restrictions</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td rowspan="25" valign="top" >DRM</td>
|
<td rowspan="35" valign="top" >DRM</td>
|
||||||
<td rowspan="4" valign="top" >Generic</td>
|
<td rowspan="4" valign="top" >Generic</td>
|
||||||
<td valign="top" >“EDID”</td>
|
<td valign="top" >“EDID”</td>
|
||||||
<td valign="top" >BLOB | IMMUTABLE</td>
|
<td valign="top" >BLOB | IMMUTABLE</td>
|
||||||
|
@ -2602,7 +2602,7 @@ void intel_crt_init(struct drm_device *dev)
|
||||||
<td valign="top" >Contains tiling information for a connector.</td>
|
<td valign="top" >Contains tiling information for a connector.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td rowspan="1" valign="top" >Plane</td>
|
<td rowspan="11" valign="top" >Plane</td>
|
||||||
<td valign="top" >“type”</td>
|
<td valign="top" >“type”</td>
|
||||||
<td valign="top" >ENUM | IMMUTABLE</td>
|
<td valign="top" >ENUM | IMMUTABLE</td>
|
||||||
<td valign="top" >{ "Overlay", "Primary", "Cursor" }</td>
|
<td valign="top" >{ "Overlay", "Primary", "Cursor" }</td>
|
||||||
|
@ -2610,6 +2610,76 @@ void intel_crt_init(struct drm_device *dev)
|
||||||
<td valign="top" >Plane type</td>
|
<td valign="top" >Plane type</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
<td valign="top" >“SRC_X”</td>
|
||||||
|
<td valign="top" >RANGE</td>
|
||||||
|
<td valign="top" >Min=0, Max=UINT_MAX</td>
|
||||||
|
<td valign="top" >Plane</td>
|
||||||
|
<td valign="top" >Scanout source x coordinate in 16.16 fixed point (atomic)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td valign="top" >“SRC_Y”</td>
|
||||||
|
<td valign="top" >RANGE</td>
|
||||||
|
<td valign="top" >Min=0, Max=UINT_MAX</td>
|
||||||
|
<td valign="top" >Plane</td>
|
||||||
|
<td valign="top" >Scanout source y coordinate in 16.16 fixed point (atomic)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td valign="top" >“SRC_W”</td>
|
||||||
|
<td valign="top" >RANGE</td>
|
||||||
|
<td valign="top" >Min=0, Max=UINT_MAX</td>
|
||||||
|
<td valign="top" >Plane</td>
|
||||||
|
<td valign="top" >Scanout source width in 16.16 fixed point (atomic)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td valign="top" >“SRC_H”</td>
|
||||||
|
<td valign="top" >RANGE</td>
|
||||||
|
<td valign="top" >Min=0, Max=UINT_MAX</td>
|
||||||
|
<td valign="top" >Plane</td>
|
||||||
|
<td valign="top" >Scanout source height in 16.16 fixed point (atomic)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td valign="top" >“CRTC_X”</td>
|
||||||
|
<td valign="top" >SIGNED_RANGE</td>
|
||||||
|
<td valign="top" >Min=INT_MIN, Max=INT_MAX</td>
|
||||||
|
<td valign="top" >Plane</td>
|
||||||
|
<td valign="top" >Scanout CRTC (destination) x coordinate (atomic)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td valign="top" >“CRTC_Y”</td>
|
||||||
|
<td valign="top" >SIGNED_RANGE</td>
|
||||||
|
<td valign="top" >Min=INT_MIN, Max=INT_MAX</td>
|
||||||
|
<td valign="top" >Plane</td>
|
||||||
|
<td valign="top" >Scanout CRTC (destination) y coordinate (atomic)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td valign="top" >“CRTC_W”</td>
|
||||||
|
<td valign="top" >RANGE</td>
|
||||||
|
<td valign="top" >Min=0, Max=UINT_MAX</td>
|
||||||
|
<td valign="top" >Plane</td>
|
||||||
|
<td valign="top" >Scanout CRTC (destination) width (atomic)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td valign="top" >“CRTC_H”</td>
|
||||||
|
<td valign="top" >RANGE</td>
|
||||||
|
<td valign="top" >Min=0, Max=UINT_MAX</td>
|
||||||
|
<td valign="top" >Plane</td>
|
||||||
|
<td valign="top" >Scanout CRTC (destination) height (atomic)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td valign="top" >“FB_ID”</td>
|
||||||
|
<td valign="top" >OBJECT</td>
|
||||||
|
<td valign="top" >DRM_MODE_OBJECT_FB</td>
|
||||||
|
<td valign="top" >Plane</td>
|
||||||
|
<td valign="top" >Scanout framebuffer (atomic)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td valign="top" >“CRTC_ID”</td>
|
||||||
|
<td valign="top" >OBJECT</td>
|
||||||
|
<td valign="top" >DRM_MODE_OBJECT_CRTC</td>
|
||||||
|
<td valign="top" >Plane</td>
|
||||||
|
<td valign="top" >CRTC that plane is attached to (atomic)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
<td rowspan="2" valign="top" >DVI-I</td>
|
<td rowspan="2" valign="top" >DVI-I</td>
|
||||||
<td valign="top" >“subconnector”</td>
|
<td valign="top" >“subconnector”</td>
|
||||||
<td valign="top" >ENUM</td>
|
<td valign="top" >ENUM</td>
|
||||||
|
|
|
@ -366,9 +366,41 @@ int drm_atomic_plane_set_property(struct drm_plane *plane,
|
||||||
struct drm_plane_state *state, struct drm_property *property,
|
struct drm_plane_state *state, struct drm_property *property,
|
||||||
uint64_t val)
|
uint64_t val)
|
||||||
{
|
{
|
||||||
if (plane->funcs->atomic_set_property)
|
struct drm_device *dev = plane->dev;
|
||||||
return plane->funcs->atomic_set_property(plane, state, property, val);
|
struct drm_mode_config *config = &dev->mode_config;
|
||||||
|
|
||||||
|
if (property == config->prop_fb_id) {
|
||||||
|
struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, val);
|
||||||
|
drm_atomic_set_fb_for_plane(state, fb);
|
||||||
|
if (fb)
|
||||||
|
drm_framebuffer_unreference(fb);
|
||||||
|
} else if (property == config->prop_crtc_id) {
|
||||||
|
struct drm_crtc *crtc = drm_crtc_find(dev, val);
|
||||||
|
return drm_atomic_set_crtc_for_plane(state, crtc);
|
||||||
|
} else if (property == config->prop_crtc_x) {
|
||||||
|
state->crtc_x = U642I64(val);
|
||||||
|
} else if (property == config->prop_crtc_y) {
|
||||||
|
state->crtc_y = U642I64(val);
|
||||||
|
} else if (property == config->prop_crtc_w) {
|
||||||
|
state->crtc_w = val;
|
||||||
|
} else if (property == config->prop_crtc_h) {
|
||||||
|
state->crtc_h = val;
|
||||||
|
} else if (property == config->prop_src_x) {
|
||||||
|
state->src_x = val;
|
||||||
|
} else if (property == config->prop_src_y) {
|
||||||
|
state->src_y = val;
|
||||||
|
} else if (property == config->prop_src_w) {
|
||||||
|
state->src_w = val;
|
||||||
|
} else if (property == config->prop_src_h) {
|
||||||
|
state->src_h = val;
|
||||||
|
} else if (plane->funcs->atomic_set_property) {
|
||||||
|
return plane->funcs->atomic_set_property(plane, state,
|
||||||
|
property, val);
|
||||||
|
} else {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_atomic_plane_set_property);
|
EXPORT_SYMBOL(drm_atomic_plane_set_property);
|
||||||
|
|
||||||
|
@ -392,9 +424,36 @@ int drm_atomic_plane_get_property(struct drm_plane *plane,
|
||||||
const struct drm_plane_state *state,
|
const struct drm_plane_state *state,
|
||||||
struct drm_property *property, uint64_t *val)
|
struct drm_property *property, uint64_t *val)
|
||||||
{
|
{
|
||||||
if (plane->funcs->atomic_get_property)
|
struct drm_device *dev = plane->dev;
|
||||||
|
struct drm_mode_config *config = &dev->mode_config;
|
||||||
|
|
||||||
|
if (property == config->prop_fb_id) {
|
||||||
|
*val = (state->fb) ? state->fb->base.id : 0;
|
||||||
|
} else if (property == config->prop_crtc_id) {
|
||||||
|
*val = (state->crtc) ? state->crtc->base.id : 0;
|
||||||
|
} else if (property == config->prop_crtc_x) {
|
||||||
|
*val = I642U64(state->crtc_x);
|
||||||
|
} else if (property == config->prop_crtc_y) {
|
||||||
|
*val = I642U64(state->crtc_y);
|
||||||
|
} else if (property == config->prop_crtc_w) {
|
||||||
|
*val = state->crtc_w;
|
||||||
|
} else if (property == config->prop_crtc_h) {
|
||||||
|
*val = state->crtc_h;
|
||||||
|
} else if (property == config->prop_src_x) {
|
||||||
|
*val = state->src_x;
|
||||||
|
} else if (property == config->prop_src_y) {
|
||||||
|
*val = state->src_y;
|
||||||
|
} else if (property == config->prop_src_w) {
|
||||||
|
*val = state->src_w;
|
||||||
|
} else if (property == config->prop_src_h) {
|
||||||
|
*val = state->src_h;
|
||||||
|
} else if (plane->funcs->atomic_get_property) {
|
||||||
return plane->funcs->atomic_get_property(plane, state, property, val);
|
return plane->funcs->atomic_get_property(plane, state, property, val);
|
||||||
|
} else {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_atomic_plane_get_property);
|
EXPORT_SYMBOL(drm_atomic_plane_get_property);
|
||||||
|
|
||||||
|
|
|
@ -1169,6 +1169,7 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
|
||||||
const uint32_t *formats, uint32_t format_count,
|
const uint32_t *formats, uint32_t format_count,
|
||||||
enum drm_plane_type type)
|
enum drm_plane_type type)
|
||||||
{
|
{
|
||||||
|
struct drm_mode_config *config = &dev->mode_config;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
|
ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
|
||||||
|
@ -1193,15 +1194,28 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
|
||||||
plane->possible_crtcs = possible_crtcs;
|
plane->possible_crtcs = possible_crtcs;
|
||||||
plane->type = type;
|
plane->type = type;
|
||||||
|
|
||||||
list_add_tail(&plane->head, &dev->mode_config.plane_list);
|
list_add_tail(&plane->head, &config->plane_list);
|
||||||
dev->mode_config.num_total_plane++;
|
config->num_total_plane++;
|
||||||
if (plane->type == DRM_PLANE_TYPE_OVERLAY)
|
if (plane->type == DRM_PLANE_TYPE_OVERLAY)
|
||||||
dev->mode_config.num_overlay_plane++;
|
config->num_overlay_plane++;
|
||||||
|
|
||||||
drm_object_attach_property(&plane->base,
|
drm_object_attach_property(&plane->base,
|
||||||
dev->mode_config.plane_type_property,
|
config->plane_type_property,
|
||||||
plane->type);
|
plane->type);
|
||||||
|
|
||||||
|
if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
|
||||||
|
drm_object_attach_property(&plane->base, config->prop_fb_id, 0);
|
||||||
|
drm_object_attach_property(&plane->base, config->prop_crtc_id, 0);
|
||||||
|
drm_object_attach_property(&plane->base, config->prop_crtc_x, 0);
|
||||||
|
drm_object_attach_property(&plane->base, config->prop_crtc_y, 0);
|
||||||
|
drm_object_attach_property(&plane->base, config->prop_crtc_w, 0);
|
||||||
|
drm_object_attach_property(&plane->base, config->prop_crtc_h, 0);
|
||||||
|
drm_object_attach_property(&plane->base, config->prop_src_x, 0);
|
||||||
|
drm_object_attach_property(&plane->base, config->prop_src_y, 0);
|
||||||
|
drm_object_attach_property(&plane->base, config->prop_src_w, 0);
|
||||||
|
drm_object_attach_property(&plane->base, config->prop_src_h, 0);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_universal_plane_init);
|
EXPORT_SYMBOL(drm_universal_plane_init);
|
||||||
|
@ -1323,7 +1337,7 @@ void drm_plane_force_disable(struct drm_plane *plane)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_plane_force_disable);
|
EXPORT_SYMBOL(drm_plane_force_disable);
|
||||||
|
|
||||||
static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
|
static int drm_mode_create_standard_properties(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
struct drm_property *prop;
|
struct drm_property *prop;
|
||||||
|
|
||||||
|
@ -1360,20 +1374,72 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
dev->mode_config.tile_property = prop;
|
dev->mode_config.tile_property = prop;
|
||||||
|
|
||||||
return 0;
|
prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
|
||||||
}
|
|
||||||
|
|
||||||
static int drm_mode_create_standard_plane_properties(struct drm_device *dev)
|
|
||||||
{
|
|
||||||
struct drm_property *type;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Standard properties (apply to all planes)
|
|
||||||
*/
|
|
||||||
type = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
|
|
||||||
"type", drm_plane_type_enum_list,
|
"type", drm_plane_type_enum_list,
|
||||||
ARRAY_SIZE(drm_plane_type_enum_list));
|
ARRAY_SIZE(drm_plane_type_enum_list));
|
||||||
dev->mode_config.plane_type_property = type;
|
if (!prop)
|
||||||
|
return -ENOMEM;
|
||||||
|
dev->mode_config.plane_type_property = prop;
|
||||||
|
|
||||||
|
prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
|
||||||
|
"SRC_X", 0, UINT_MAX);
|
||||||
|
if (!prop)
|
||||||
|
return -ENOMEM;
|
||||||
|
dev->mode_config.prop_src_x = prop;
|
||||||
|
|
||||||
|
prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
|
||||||
|
"SRC_Y", 0, UINT_MAX);
|
||||||
|
if (!prop)
|
||||||
|
return -ENOMEM;
|
||||||
|
dev->mode_config.prop_src_y = prop;
|
||||||
|
|
||||||
|
prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
|
||||||
|
"SRC_W", 0, UINT_MAX);
|
||||||
|
if (!prop)
|
||||||
|
return -ENOMEM;
|
||||||
|
dev->mode_config.prop_src_w = prop;
|
||||||
|
|
||||||
|
prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
|
||||||
|
"SRC_H", 0, UINT_MAX);
|
||||||
|
if (!prop)
|
||||||
|
return -ENOMEM;
|
||||||
|
dev->mode_config.prop_src_h = prop;
|
||||||
|
|
||||||
|
prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
|
||||||
|
"CRTC_X", INT_MIN, INT_MAX);
|
||||||
|
if (!prop)
|
||||||
|
return -ENOMEM;
|
||||||
|
dev->mode_config.prop_crtc_x = prop;
|
||||||
|
|
||||||
|
prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
|
||||||
|
"CRTC_Y", INT_MIN, INT_MAX);
|
||||||
|
if (!prop)
|
||||||
|
return -ENOMEM;
|
||||||
|
dev->mode_config.prop_crtc_y = prop;
|
||||||
|
|
||||||
|
prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
|
||||||
|
"CRTC_W", 0, INT_MAX);
|
||||||
|
if (!prop)
|
||||||
|
return -ENOMEM;
|
||||||
|
dev->mode_config.prop_crtc_w = prop;
|
||||||
|
|
||||||
|
prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
|
||||||
|
"CRTC_H", 0, INT_MAX);
|
||||||
|
if (!prop)
|
||||||
|
return -ENOMEM;
|
||||||
|
dev->mode_config.prop_crtc_h = prop;
|
||||||
|
|
||||||
|
prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
|
||||||
|
"FB_ID", DRM_MODE_OBJECT_FB);
|
||||||
|
if (!prop)
|
||||||
|
return -ENOMEM;
|
||||||
|
dev->mode_config.prop_fb_id = prop;
|
||||||
|
|
||||||
|
prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
|
||||||
|
"CRTC_ID", DRM_MODE_OBJECT_CRTC);
|
||||||
|
if (!prop)
|
||||||
|
return -ENOMEM;
|
||||||
|
dev->mode_config.prop_crtc_id = prop;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -5264,8 +5330,7 @@ void drm_mode_config_init(struct drm_device *dev)
|
||||||
idr_init(&dev->mode_config.tile_idr);
|
idr_init(&dev->mode_config.tile_idr);
|
||||||
|
|
||||||
drm_modeset_lock_all(dev);
|
drm_modeset_lock_all(dev);
|
||||||
drm_mode_create_standard_connector_properties(dev);
|
drm_mode_create_standard_properties(dev);
|
||||||
drm_mode_create_standard_plane_properties(dev);
|
|
||||||
drm_modeset_unlock_all(dev);
|
drm_modeset_unlock_all(dev);
|
||||||
|
|
||||||
/* Just to be sure */
|
/* Just to be sure */
|
||||||
|
|
|
@ -1099,6 +1099,16 @@ struct drm_mode_config {
|
||||||
struct drm_property *tile_property;
|
struct drm_property *tile_property;
|
||||||
struct drm_property *plane_type_property;
|
struct drm_property *plane_type_property;
|
||||||
struct drm_property *rotation_property;
|
struct drm_property *rotation_property;
|
||||||
|
struct drm_property *prop_src_x;
|
||||||
|
struct drm_property *prop_src_y;
|
||||||
|
struct drm_property *prop_src_w;
|
||||||
|
struct drm_property *prop_src_h;
|
||||||
|
struct drm_property *prop_crtc_x;
|
||||||
|
struct drm_property *prop_crtc_y;
|
||||||
|
struct drm_property *prop_crtc_w;
|
||||||
|
struct drm_property *prop_crtc_h;
|
||||||
|
struct drm_property *prop_fb_id;
|
||||||
|
struct drm_property *prop_crtc_id;
|
||||||
|
|
||||||
/* DVI-I properties */
|
/* DVI-I properties */
|
||||||
struct drm_property *dvi_i_subconnector_property;
|
struct drm_property *dvi_i_subconnector_property;
|
||||||
|
|
Loading…
Reference in a new issue