Commit 818ed961 authored by Maarten Lankhorst's avatar Maarten Lankhorst Committed by Daniel Vetter

drm/i915: Make setting color key atomic.

By making color key atomic there are no more transitional helpers.
The plane check function will reject the color key when a scaler is
active.
Signed-off-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: default avatarMatt Roper <matthew.d.roper@intel.com>
Tested-by(IVB): Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent eddfcbcd
...@@ -56,6 +56,7 @@ intel_create_plane_state(struct drm_plane *plane) ...@@ -56,6 +56,7 @@ intel_create_plane_state(struct drm_plane *plane)
state->base.plane = plane; state->base.plane = plane;
state->base.rotation = BIT(DRM_ROTATE_0); state->base.rotation = BIT(DRM_ROTATE_0);
state->ckey.flags = I915_SET_COLORKEY_NONE;
return state; return state;
} }
......
...@@ -4411,9 +4411,9 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state, ...@@ -4411,9 +4411,9 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
return ret; return ret;
/* check colorkey */ /* check colorkey */
if (WARN_ON(intel_plane->ckey.flags != I915_SET_COLORKEY_NONE)) { if (plane_state->ckey.flags != I915_SET_COLORKEY_NONE) {
DRM_DEBUG_KMS("[PLANE:%d] scaling with color key not allowed", DRM_DEBUG_KMS("[PLANE:%d] scaling with color key not allowed",
intel_plane->base.base.id); intel_plane->base.base.id);
return -EINVAL; return -EINVAL;
} }
...@@ -13746,7 +13746,7 @@ intel_check_primary_plane(struct drm_plane *plane, ...@@ -13746,7 +13746,7 @@ intel_check_primary_plane(struct drm_plane *plane,
/* use scaler when colorkey is not required */ /* use scaler when colorkey is not required */
if (INTEL_INFO(plane->dev)->gen >= 9 && if (INTEL_INFO(plane->dev)->gen >= 9 &&
to_intel_plane(plane)->ckey.flags == I915_SET_COLORKEY_NONE) { state->ckey.flags == I915_SET_COLORKEY_NONE) {
min_scale = 1; min_scale = 1;
max_scale = skl_max_scale(to_intel_crtc(crtc), crtc_state); max_scale = skl_max_scale(to_intel_crtc(crtc), crtc_state);
can_position = true; can_position = true;
...@@ -13892,7 +13892,6 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev, ...@@ -13892,7 +13892,6 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
primary->check_plane = intel_check_primary_plane; primary->check_plane = intel_check_primary_plane;
primary->commit_plane = intel_commit_primary_plane; primary->commit_plane = intel_commit_primary_plane;
primary->disable_plane = intel_disable_primary_plane; primary->disable_plane = intel_disable_primary_plane;
primary->ckey.flags = I915_SET_COLORKEY_NONE;
if (HAS_FBC(dev) && INTEL_INFO(dev)->gen < 4) if (HAS_FBC(dev) && INTEL_INFO(dev)->gen < 4)
primary->plane = !pipe; primary->plane = !pipe;
......
...@@ -274,6 +274,8 @@ struct intel_plane_state { ...@@ -274,6 +274,8 @@ struct intel_plane_state {
* update_scaler_plane. * update_scaler_plane.
*/ */
int scaler_id; int scaler_id;
struct drm_intel_sprite_colorkey ckey;
}; };
struct intel_initial_plane_config { struct intel_initial_plane_config {
...@@ -588,9 +590,6 @@ struct intel_plane { ...@@ -588,9 +590,6 @@ struct intel_plane {
bool can_scale; bool can_scale;
int max_downscale; int max_downscale;
/* FIXME convert to properties */
struct drm_intel_sprite_colorkey ckey;
/* Since we need to change the watermarks before/after /* Since we need to change the watermarks before/after
* enabling/disabling the planes, we need to store the parameters here * enabling/disabling the planes, we need to store the parameters here
* as the other pieces of the struct may not reflect the values we want * as the other pieces of the struct may not reflect the values we want
...@@ -1392,7 +1391,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob); ...@@ -1392,7 +1391,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
/* intel_sprite.c */ /* intel_sprite.c */
int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane); int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
int intel_plane_restore(struct drm_plane *plane);
int intel_sprite_set_colorkey(struct drm_device *dev, void *data, int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
struct drm_file *file_priv); struct drm_file *file_priv);
bool intel_pipe_update_start(struct intel_crtc *crtc, bool intel_pipe_update_start(struct intel_crtc *crtc,
......
...@@ -182,7 +182,8 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc, ...@@ -182,7 +182,8 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
const int plane = intel_plane->plane + 1; const int plane = intel_plane->plane + 1;
u32 plane_ctl, stride_div, stride; u32 plane_ctl, stride_div, stride;
int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
const struct drm_intel_sprite_colorkey *key = &intel_plane->ckey; const struct drm_intel_sprite_colorkey *key =
&to_intel_plane_state(drm_plane->state)->ckey;
unsigned long surf_addr; unsigned long surf_addr;
u32 tile_height, plane_offset, plane_size; u32 tile_height, plane_offset, plane_size;
unsigned int rotation; unsigned int rotation;
...@@ -344,7 +345,8 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc, ...@@ -344,7 +345,8 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
u32 sprctl; u32 sprctl;
unsigned long sprsurf_offset, linear_offset; unsigned long sprsurf_offset, linear_offset;
int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
const struct drm_intel_sprite_colorkey *key = &intel_plane->ckey; const struct drm_intel_sprite_colorkey *key =
&to_intel_plane_state(dplane->state)->ckey;
sprctl = SP_ENABLE; sprctl = SP_ENABLE;
...@@ -488,7 +490,8 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, ...@@ -488,7 +490,8 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
u32 sprctl, sprscale = 0; u32 sprctl, sprscale = 0;
unsigned long sprsurf_offset, linear_offset; unsigned long sprsurf_offset, linear_offset;
int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
const struct drm_intel_sprite_colorkey *key = &intel_plane->ckey; const struct drm_intel_sprite_colorkey *key =
&to_intel_plane_state(plane->state)->ckey;
sprctl = SPRITE_ENABLE; sprctl = SPRITE_ENABLE;
...@@ -629,7 +632,8 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, ...@@ -629,7 +632,8 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
unsigned long dvssurf_offset, linear_offset; unsigned long dvssurf_offset, linear_offset;
u32 dvscntr, dvsscale; u32 dvscntr, dvsscale;
int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
const struct drm_intel_sprite_colorkey *key = &intel_plane->ckey; const struct drm_intel_sprite_colorkey *key =
&to_intel_plane_state(plane->state)->ckey;
dvscntr = DVS_ENABLE; dvscntr = DVS_ENABLE;
...@@ -781,7 +785,7 @@ intel_check_sprite_plane(struct drm_plane *plane, ...@@ -781,7 +785,7 @@ intel_check_sprite_plane(struct drm_plane *plane,
/* setup can_scale, min_scale, max_scale */ /* setup can_scale, min_scale, max_scale */
if (INTEL_INFO(dev)->gen >= 9) { if (INTEL_INFO(dev)->gen >= 9) {
/* use scaler when colorkey is not required */ /* use scaler when colorkey is not required */
if (intel_plane->ckey.flags == I915_SET_COLORKEY_NONE) { if (state->ckey.flags == I915_SET_COLORKEY_NONE) {
can_scale = 1; can_scale = 1;
min_scale = 1; min_scale = 1;
max_scale = skl_max_scale(intel_crtc, crtc_state); max_scale = skl_max_scale(intel_crtc, crtc_state);
...@@ -801,7 +805,6 @@ intel_check_sprite_plane(struct drm_plane *plane, ...@@ -801,7 +805,6 @@ intel_check_sprite_plane(struct drm_plane *plane,
* coordinates and sizes. We probably need some way to decide whether * coordinates and sizes. We probably need some way to decide whether
* more strict checking should be done instead. * more strict checking should be done instead.
*/ */
drm_rect_rotate(src, fb->width << 16, fb->height << 16, drm_rect_rotate(src, fb->width << 16, fb->height << 16,
state->base.rotation); state->base.rotation);
...@@ -811,7 +814,7 @@ intel_check_sprite_plane(struct drm_plane *plane, ...@@ -811,7 +814,7 @@ intel_check_sprite_plane(struct drm_plane *plane,
vscale = drm_rect_calc_vscale_relaxed(src, dst, min_scale, max_scale); vscale = drm_rect_calc_vscale_relaxed(src, dst, min_scale, max_scale);
BUG_ON(vscale < 0); BUG_ON(vscale < 0);
state->visible = drm_rect_clip_scaled(src, dst, clip, hscale, vscale); state->visible = drm_rect_clip_scaled(src, dst, clip, hscale, vscale);
crtc_x = dst->x1; crtc_x = dst->x1;
crtc_y = dst->y1; crtc_y = dst->y1;
...@@ -953,7 +956,9 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data, ...@@ -953,7 +956,9 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
{ {
struct drm_intel_sprite_colorkey *set = data; struct drm_intel_sprite_colorkey *set = data;
struct drm_plane *plane; struct drm_plane *plane;
struct intel_plane *intel_plane; struct drm_plane_state *plane_state;
struct drm_atomic_state *state;
struct drm_modeset_acquire_ctx ctx;
int ret = 0; int ret = 0;
/* Make sure we don't try to enable both src & dest simultaneously */ /* Make sure we don't try to enable both src & dest simultaneously */
...@@ -964,50 +969,41 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data, ...@@ -964,50 +969,41 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
set->flags & I915_SET_COLORKEY_DESTINATION) set->flags & I915_SET_COLORKEY_DESTINATION)
return -EINVAL; return -EINVAL;
drm_modeset_lock_all(dev);
plane = drm_plane_find(dev, set->plane_id); plane = drm_plane_find(dev, set->plane_id);
if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY) { if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
ret = -ENOENT; return -ENOENT;
goto out_unlock;
}
intel_plane = to_intel_plane(plane); drm_modeset_acquire_init(&ctx, 0);
if (INTEL_INFO(dev)->gen >= 9) { state = drm_atomic_state_alloc(plane->dev);
/* plane scaling and colorkey are mutually exclusive */ if (!state) {
if (to_intel_plane_state(plane->state)->scaler_id >= 0) { ret = -ENOMEM;
DRM_ERROR("colorkey not allowed with scaler\n"); goto out;
ret = -EINVAL;
goto out_unlock;
}
} }
state->acquire_ctx = &ctx;
while (1) {
plane_state = drm_atomic_get_plane_state(state, plane);
ret = PTR_ERR_OR_ZERO(plane_state);
if (!ret) {
to_intel_plane_state(plane_state)->ckey = *set;
ret = drm_atomic_commit(state);
}
intel_plane->ckey = *set; if (ret != -EDEADLK)
break;
/*
* The only way this could fail would be due to
* the current plane state being unsupportable already,
* and we dont't consider that an error for the
* colorkey ioctl. So just ignore any error.
*/
intel_plane_restore(plane);
out_unlock: drm_atomic_state_clear(state);
drm_modeset_unlock_all(dev); drm_modeset_backoff(&ctx);
return ret; }
}
int intel_plane_restore(struct drm_plane *plane) if (ret)
{ drm_atomic_state_free(state);
if (!plane->crtc || !plane->state->fb)
return 0;
return drm_plane_helper_update(plane, plane->crtc, plane->state->fb, out:
plane->state->crtc_x, plane->state->crtc_y, drm_modeset_drop_locks(&ctx);
plane->state->crtc_w, plane->state->crtc_h, drm_modeset_acquire_fini(&ctx);
plane->state->src_x, plane->state->src_y, return ret;
plane->state->src_w, plane->state->src_h);
} }
static const uint32_t ilk_plane_formats[] = { static const uint32_t ilk_plane_formats[] = {
...@@ -1136,7 +1132,6 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) ...@@ -1136,7 +1132,6 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
intel_plane->plane = plane; intel_plane->plane = plane;
intel_plane->check_plane = intel_check_sprite_plane; intel_plane->check_plane = intel_check_sprite_plane;
intel_plane->commit_plane = intel_commit_sprite_plane; intel_plane->commit_plane = intel_commit_sprite_plane;
intel_plane->ckey.flags = I915_SET_COLORKEY_NONE;
possible_crtcs = (1 << pipe); possible_crtcs = (1 << pipe);
ret = drm_universal_plane_init(dev, &intel_plane->base, possible_crtcs, ret = drm_universal_plane_init(dev, &intel_plane->base, possible_crtcs,
&intel_plane_funcs, &intel_plane_funcs,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment