Commit 86adf9d7 authored by Maarten Lankhorst's avatar Maarten Lankhorst Committed by Daniel Vetter

drm/i915: Split skl_update_scaler, v4.

commit 2c310b9d2859863826c3688c88218d607d5dd19a
Author: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Date:   Mon May 18 12:28:52 2015 +0200

drm/i915: Split skl_update_scaler, v4.

It's easier to read separate functions for crtc and plane scaler state.

Changes since v1:
 - Update documentation.
Changes since v2:
 - Get rid of parameters to skl_update_scaler only used for traces.
   This avoids needing to document the other parameters.
Changes since v3:
 - Rename scaler_idx to scaler_user.
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 ad421372
...@@ -4313,62 +4313,16 @@ static void cpt_verify_modeset(struct drm_device *dev, int pipe) ...@@ -4313,62 +4313,16 @@ static void cpt_verify_modeset(struct drm_device *dev, int pipe)
} }
} }
/** static int
* skl_update_scaler_users - Stages update to crtc's scaler state skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
* @intel_crtc: crtc unsigned scaler_user, int *scaler_id, unsigned int rotation,
* @crtc_state: crtc_state int src_w, int src_h, int dst_w, int dst_h)
* @plane: plane (NULL indicates crtc is requesting update)
* @plane_state: plane's state
* @force_detach: request unconditional detachment of scaler
*
* This function updates scaler state for requested plane or crtc.
* To request scaler usage update for a plane, caller shall pass plane pointer.
* To request scaler usage update for crtc, caller shall pass plane pointer
* as NULL.
*
* Return
* 0 - scaler_usage updated successfully
* error - requested scaling cannot be supported or other error condition
*/
int
skl_update_scaler_users(
struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state,
struct intel_plane *intel_plane, struct intel_plane_state *plane_state,
int force_detach)
{ {
struct intel_crtc_scaler_state *scaler_state =
&crtc_state->scaler_state;
struct intel_crtc *intel_crtc =
to_intel_crtc(crtc_state->base.crtc);
int need_scaling; int need_scaling;
int idx;
int src_w, src_h, dst_w, dst_h;
int *scaler_id;
struct drm_framebuffer *fb;
struct intel_crtc_scaler_state *scaler_state;
unsigned int rotation;
if (!intel_crtc || !crtc_state)
return 0;
scaler_state = &crtc_state->scaler_state;
idx = intel_plane ? drm_plane_index(&intel_plane->base) : SKL_CRTC_INDEX;
fb = intel_plane ? plane_state->base.fb : NULL;
if (intel_plane) {
src_w = drm_rect_width(&plane_state->src) >> 16;
src_h = drm_rect_height(&plane_state->src) >> 16;
dst_w = drm_rect_width(&plane_state->dst);
dst_h = drm_rect_height(&plane_state->dst);
scaler_id = &plane_state->scaler_id;
rotation = plane_state->base.rotation;
} else {
struct drm_display_mode *adjusted_mode =
&crtc_state->base.adjusted_mode;
src_w = crtc_state->pipe_src_w;
src_h = crtc_state->pipe_src_h;
dst_w = adjusted_mode->hdisplay;
dst_h = adjusted_mode->vdisplay;
scaler_id = &scaler_state->scaler_id;
rotation = DRM_ROTATE_0;
}
need_scaling = intel_rotation_90_or_270(rotation) ? need_scaling = intel_rotation_90_or_270(rotation) ?
(src_h != dst_w || src_w != dst_h): (src_h != dst_w || src_w != dst_h):
...@@ -4384,17 +4338,14 @@ skl_update_scaler_users( ...@@ -4384,17 +4338,14 @@ skl_update_scaler_users(
* update to free the scaler is done in plane/panel-fit programming. * update to free the scaler is done in plane/panel-fit programming.
* For this purpose crtc/plane_state->scaler_id isn't reset here. * For this purpose crtc/plane_state->scaler_id isn't reset here.
*/ */
if (force_detach || !need_scaling || (intel_plane && if (force_detach || !need_scaling) {
(!fb || !plane_state->visible))) {
if (*scaler_id >= 0) { if (*scaler_id >= 0) {
scaler_state->scaler_users &= ~(1 << idx); scaler_state->scaler_users &= ~(1 << scaler_user);
scaler_state->scalers[*scaler_id].in_use = 0; scaler_state->scalers[*scaler_id].in_use = 0;
DRM_DEBUG_KMS("Staged freeing scaler id %d.%d from %s:%d " DRM_DEBUG_KMS("scaler_user index %u.%u: "
"crtc_state = %p scaler_users = 0x%x\n", "Staged freeing scaler id %d scaler_users = 0x%x\n",
intel_crtc->pipe, *scaler_id, intel_plane ? "PLANE" : "CRTC", intel_crtc->pipe, scaler_user, *scaler_id,
intel_plane ? intel_plane->base.base.id :
intel_crtc->base.base.id, crtc_state,
scaler_state->scaler_users); scaler_state->scaler_users);
*scaler_id = -1; *scaler_id = -1;
} }
...@@ -4407,51 +4358,112 @@ skl_update_scaler_users( ...@@ -4407,51 +4358,112 @@ skl_update_scaler_users(
src_w > SKL_MAX_SRC_W || src_h > SKL_MAX_SRC_H || src_w > SKL_MAX_SRC_W || src_h > SKL_MAX_SRC_H ||
dst_w > SKL_MAX_DST_W || dst_h > SKL_MAX_DST_H) { dst_w > SKL_MAX_DST_W || dst_h > SKL_MAX_DST_H) {
DRM_DEBUG_KMS("%s:%d scaler_user index %u.%u: src %ux%u dst %ux%u " DRM_DEBUG_KMS("scaler_user index %u.%u: src %ux%u dst %ux%u "
"size is out of scaler range\n", "size is out of scaler range\n",
intel_plane ? "PLANE" : "CRTC", intel_crtc->pipe, scaler_user, src_w, src_h, dst_w, dst_h);
intel_plane ? intel_plane->base.base.id : intel_crtc->base.base.id,
intel_crtc->pipe, idx, src_w, src_h, dst_w, dst_h);
return -EINVAL; return -EINVAL;
} }
/* mark this plane as a scaler user in crtc_state */
scaler_state->scaler_users |= (1 << scaler_user);
DRM_DEBUG_KMS("scaler_user index %u.%u: "
"staged scaling request for %ux%u->%ux%u scaler_users = 0x%x\n",
intel_crtc->pipe, scaler_user, src_w, src_h, dst_w, dst_h,
scaler_state->scaler_users);
return 0;
}
/**
* skl_update_scaler_crtc - Stages update to scaler state for a given crtc.
*
* @state: crtc's scaler state
* @force_detach: whether to forcibly disable scaler
*
* Return
* 0 - scaler_usage updated successfully
* error - requested scaling cannot be supported or other error condition
*/
int skl_update_scaler_crtc(struct intel_crtc_state *state, int force_detach)
{
struct intel_crtc *intel_crtc = to_intel_crtc(state->base.crtc);
struct drm_display_mode *adjusted_mode =
&state->base.adjusted_mode;
DRM_DEBUG_KMS("Updating scaler for [CRTC:%i] scaler_user index %u.%u\n",
intel_crtc->base.base.id, intel_crtc->pipe, SKL_CRTC_INDEX);
return skl_update_scaler(state, force_detach, SKL_CRTC_INDEX,
&state->scaler_state.scaler_id, DRM_ROTATE_0,
state->pipe_src_w, state->pipe_src_h,
adjusted_mode->hdisplay, adjusted_mode->hdisplay);
}
/**
* skl_update_scaler_plane - Stages update to scaler state for a given plane.
*
* @state: crtc's scaler state
* @intel_plane: affected plane
* @plane_state: atomic plane state to update
*
* Return
* 0 - scaler_usage updated successfully
* error - requested scaling cannot be supported or other error condition
*/
int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
struct intel_plane *intel_plane,
struct intel_plane_state *plane_state)
{
struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
struct drm_framebuffer *fb = plane_state->base.fb;
int ret;
bool force_detach = !fb || !plane_state->visible;
DRM_DEBUG_KMS("Updating scaler for [PLANE:%d] scaler_user index %u.%u\n",
intel_plane->base.base.id, intel_crtc->pipe,
drm_plane_index(&intel_plane->base));
ret = skl_update_scaler(crtc_state, force_detach,
drm_plane_index(&intel_plane->base),
&plane_state->scaler_id,
plane_state->base.rotation,
drm_rect_width(&plane_state->src) >> 16,
drm_rect_height(&plane_state->src) >> 16,
drm_rect_width(&plane_state->dst),
drm_rect_height(&plane_state->dst));
if (ret || plane_state->scaler_id < 0)
return ret;
/* check colorkey */ /* check colorkey */
if (WARN_ON(intel_plane && if (WARN_ON(intel_plane->ckey.flags != I915_SET_COLORKEY_NONE)) {
intel_plane->ckey.flags != I915_SET_COLORKEY_NONE)) { DRM_DEBUG_KMS("[PLANE:%d] scaling with color key not allowed",
DRM_DEBUG_KMS("PLANE:%d scaling %ux%u->%ux%u not allowed with colorkey", intel_plane->base.base.id);
intel_plane->base.base.id, src_w, src_h, dst_w, dst_h);
return -EINVAL; return -EINVAL;
} }
/* Check src format */ /* Check src format */
if (intel_plane) { switch (fb->pixel_format) {
switch (fb->pixel_format) { case DRM_FORMAT_RGB565:
case DRM_FORMAT_RGB565: case DRM_FORMAT_XBGR8888:
case DRM_FORMAT_XBGR8888: case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_XRGB8888: case DRM_FORMAT_ABGR8888:
case DRM_FORMAT_ABGR8888: case DRM_FORMAT_ARGB8888:
case DRM_FORMAT_ARGB8888: case DRM_FORMAT_XRGB2101010:
case DRM_FORMAT_XRGB2101010: case DRM_FORMAT_XBGR2101010:
case DRM_FORMAT_XBGR2101010: case DRM_FORMAT_YUYV:
case DRM_FORMAT_YUYV: case DRM_FORMAT_YVYU:
case DRM_FORMAT_YVYU: case DRM_FORMAT_UYVY:
case DRM_FORMAT_UYVY: case DRM_FORMAT_VYUY:
case DRM_FORMAT_VYUY: break;
break; default:
default: DRM_DEBUG_KMS("[PLANE:%d] FB:%d unsupported scaling format 0x%x\n",
DRM_DEBUG_KMS("PLANE:%d FB:%d unsupported scaling format 0x%x\n", intel_plane->base.base.id, fb->base.id, fb->pixel_format);
intel_plane->base.base.id, fb->base.id, fb->pixel_format); return -EINVAL;
return -EINVAL;
}
} }
/* mark this plane as a scaler user in crtc_state */
scaler_state->scaler_users |= (1 << idx);
DRM_DEBUG_KMS("%s:%d staged scaling request for %ux%u->%ux%u "
"crtc_state = %p scaler_users = 0x%x\n",
intel_plane ? "PLANE" : "CRTC",
intel_plane ? intel_plane->base.base.id : intel_crtc->base.base.id,
src_w, src_h, dst_w, dst_h, crtc_state, scaler_state->scaler_users);
return 0; return 0;
} }
...@@ -4466,7 +4478,7 @@ static void skylake_pfit_update(struct intel_crtc *crtc, int enable) ...@@ -4466,7 +4478,7 @@ static void skylake_pfit_update(struct intel_crtc *crtc, int enable)
DRM_DEBUG_KMS("for crtc_state = %p\n", crtc->config); DRM_DEBUG_KMS("for crtc_state = %p\n", crtc->config);
/* To update pfit, first update scaler state */ /* To update pfit, first update scaler state */
skl_update_scaler_users(crtc, crtc->config, NULL, NULL, !enable); skl_update_scaler_crtc(crtc->config, !enable);
intel_atomic_setup_scalers(crtc->base.dev, crtc, crtc->config); intel_atomic_setup_scalers(crtc->base.dev, crtc, crtc->config);
skl_detach_scalers(crtc); skl_detach_scalers(crtc);
if (!enable) if (!enable)
...@@ -13660,8 +13672,9 @@ intel_check_primary_plane(struct drm_plane *plane, ...@@ -13660,8 +13672,9 @@ intel_check_primary_plane(struct drm_plane *plane,
} }
if (INTEL_INFO(dev)->gen >= 9) { if (INTEL_INFO(dev)->gen >= 9) {
ret = skl_update_scaler_users(intel_crtc, crtc_state, ret = skl_update_scaler_plane(crtc_state,
to_intel_plane(plane), state, 0); to_intel_plane(plane),
state);
if (ret) if (ret)
return ret; return ret;
} }
......
...@@ -1382,7 +1382,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, ...@@ -1382,7 +1382,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
if (INTEL_INFO(dev)->gen >= 9) { if (INTEL_INFO(dev)->gen >= 9) {
int ret; int ret;
ret = skl_update_scaler_users(intel_crtc, pipe_config, NULL, NULL, 0); ret = skl_update_scaler_crtc(pipe_config, 0);
if (ret) if (ret)
return ret; return ret;
} }
......
...@@ -263,7 +263,7 @@ struct intel_plane_state { ...@@ -263,7 +263,7 @@ struct intel_plane_state {
* plane requiring a scaler: * plane requiring a scaler:
* - During check_plane, its bit is set in * - During check_plane, its bit is set in
* crtc_state->scaler_state.scaler_users by calling helper function * crtc_state->scaler_state.scaler_users by calling helper function
* update_scaler_users. * update_scaler_plane.
* - scaler_id indicates the scaler it got assigned. * - scaler_id indicates the scaler it got assigned.
* *
* plane doesn't require a scaler: * plane doesn't require a scaler:
...@@ -271,7 +271,7 @@ struct intel_plane_state { ...@@ -271,7 +271,7 @@ struct intel_plane_state {
* got disabled. * got disabled.
* - During check_plane, corresponding bit is reset in * - During check_plane, corresponding bit is reset in
* crtc_state->scaler_state.scaler_users by calling helper function * crtc_state->scaler_state.scaler_users by calling helper function
* update_scaler_users. * update_scaler_plane.
*/ */
int scaler_id; int scaler_id;
}; };
...@@ -1148,9 +1148,11 @@ void intel_mode_from_pipe_config(struct drm_display_mode *mode, ...@@ -1148,9 +1148,11 @@ void intel_mode_from_pipe_config(struct drm_display_mode *mode,
void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc); void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc);
void intel_modeset_preclose(struct drm_device *dev, struct drm_file *file); void intel_modeset_preclose(struct drm_device *dev, struct drm_file *file);
void skl_detach_scalers(struct intel_crtc *intel_crtc); void skl_detach_scalers(struct intel_crtc *intel_crtc);
int skl_update_scaler_users(struct intel_crtc *intel_crtc, int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
struct intel_crtc_state *crtc_state, struct intel_plane *intel_plane, struct intel_plane *intel_plane,
struct intel_plane_state *plane_state, int force_detach); struct intel_plane_state *plane_state);
int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state, int force_detach);
int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state); int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state);
unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane, unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
......
...@@ -944,8 +944,7 @@ intel_check_sprite_plane(struct drm_plane *plane, ...@@ -944,8 +944,7 @@ intel_check_sprite_plane(struct drm_plane *plane,
} }
if (INTEL_INFO(dev)->gen >= 9) { if (INTEL_INFO(dev)->gen >= 9) {
ret = skl_update_scaler_users(intel_crtc, crtc_state, intel_plane, ret = skl_update_scaler_plane(crtc_state, intel_plane, state);
state, 0);
if (ret) if (ret)
return ret; return ret;
} }
......
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