Commit e435d6e5 authored by Maarten Lankhorst's avatar Maarten Lankhorst Committed by Daniel Vetter

drm/i915: Do not update pfit state when toggling crtc enabled.

There's not much point for calculating the changes for the old
state. Instead just disable all scalers when disabling. It's
probably good enough to just disable the crtc_scaler, but just in
case there's a bug disable all scalers.

This means intel_atomic_setup_scalers is only called in the crtc
check function now, so all the transitional code can be removed.
Signed-off-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: default avatarDaniel Stone <daniels@collabora.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 8a75d157
...@@ -272,17 +272,12 @@ int intel_atomic_setup_scalers(struct drm_device *dev, ...@@ -272,17 +272,12 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
struct drm_plane *plane = NULL; struct drm_plane *plane = NULL;
struct intel_plane *intel_plane; struct intel_plane *intel_plane;
struct intel_plane_state *plane_state = NULL; struct intel_plane_state *plane_state = NULL;
struct intel_crtc_scaler_state *scaler_state; struct intel_crtc_scaler_state *scaler_state =
struct drm_atomic_state *drm_state; &crtc_state->scaler_state;
struct drm_atomic_state *drm_state = crtc_state->base.state;
int num_scalers_need; int num_scalers_need;
int i, j; int i, j;
if (INTEL_INFO(dev)->gen < 9 || !intel_crtc || !crtc_state)
return 0;
scaler_state = &crtc_state->scaler_state;
drm_state = crtc_state->base.state;
num_scalers_need = hweight32(scaler_state->scaler_users); num_scalers_need = hweight32(scaler_state->scaler_users);
DRM_DEBUG_KMS("crtc_state = %p need = %d avail = %d scaler_users = 0x%x\n", DRM_DEBUG_KMS("crtc_state = %p need = %d avail = %d scaler_users = 0x%x\n",
crtc_state, num_scalers_need, intel_crtc->num_scalers, crtc_state, num_scalers_need, intel_crtc->num_scalers,
...@@ -326,9 +321,6 @@ int intel_atomic_setup_scalers(struct drm_device *dev, ...@@ -326,9 +321,6 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
} else { } else {
name = "PLANE"; name = "PLANE";
if (!drm_state)
continue;
/* plane scaler case: assign as a plane scaler */ /* plane scaler case: assign as a plane scaler */
/* find the plane that set the bit as scaler_user */ /* find the plane that set the bit as scaler_user */
plane = drm_state->planes[i]; plane = drm_state->planes[i];
......
...@@ -2911,29 +2911,32 @@ unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane, ...@@ -2911,29 +2911,32 @@ unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
return i915_gem_obj_ggtt_offset_view(obj, view); return i915_gem_obj_ggtt_offset_view(obj, view);
} }
static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id)
{
struct drm_device *dev = intel_crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
I915_WRITE(SKL_PS_CTRL(intel_crtc->pipe, id), 0);
I915_WRITE(SKL_PS_WIN_POS(intel_crtc->pipe, id), 0);
I915_WRITE(SKL_PS_WIN_SZ(intel_crtc->pipe, id), 0);
DRM_DEBUG_KMS("CRTC:%d Disabled scaler id %u.%u\n",
intel_crtc->base.base.id, intel_crtc->pipe, id);
}
/* /*
* This function detaches (aka. unbinds) unused scalers in hardware * This function detaches (aka. unbinds) unused scalers in hardware
*/ */
static void skl_detach_scalers(struct intel_crtc *intel_crtc) static void skl_detach_scalers(struct intel_crtc *intel_crtc)
{ {
struct drm_device *dev;
struct drm_i915_private *dev_priv;
struct intel_crtc_scaler_state *scaler_state; struct intel_crtc_scaler_state *scaler_state;
int i; int i;
dev = intel_crtc->base.dev;
dev_priv = dev->dev_private;
scaler_state = &intel_crtc->config->scaler_state; scaler_state = &intel_crtc->config->scaler_state;
/* loop through and disable scalers that aren't in use */ /* loop through and disable scalers that aren't in use */
for (i = 0; i < intel_crtc->num_scalers; i++) { for (i = 0; i < intel_crtc->num_scalers; i++) {
if (!scaler_state->scalers[i].in_use) { if (!scaler_state->scalers[i].in_use)
I915_WRITE(SKL_PS_CTRL(intel_crtc->pipe, i), 0); skl_detach_scaler(intel_crtc, i);
I915_WRITE(SKL_PS_WIN_POS(intel_crtc->pipe, i), 0);
I915_WRITE(SKL_PS_WIN_SZ(intel_crtc->pipe, i), 0);
DRM_DEBUG_KMS("CRTC:%d Disabled scaler id %u.%u\n",
intel_crtc->base.base.id, intel_crtc->pipe, i);
}
} }
} }
...@@ -4364,13 +4367,12 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, ...@@ -4364,13 +4367,12 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
* skl_update_scaler_crtc - Stages update to scaler state for a given crtc. * skl_update_scaler_crtc - Stages update to scaler state for a given crtc.
* *
* @state: crtc's scaler state * @state: crtc's scaler state
* @force_detach: whether to forcibly disable scaler
* *
* Return * Return
* 0 - scaler_usage updated successfully * 0 - scaler_usage updated successfully
* error - requested scaling cannot be supported or other error condition * error - requested scaling cannot be supported or other error condition
*/ */
int skl_update_scaler_crtc(struct intel_crtc_state *state, int force_detach) int skl_update_scaler_crtc(struct intel_crtc_state *state)
{ {
struct intel_crtc *intel_crtc = to_intel_crtc(state->base.crtc); struct intel_crtc *intel_crtc = to_intel_crtc(state->base.crtc);
struct drm_display_mode *adjusted_mode = struct drm_display_mode *adjusted_mode =
...@@ -4379,7 +4381,7 @@ int skl_update_scaler_crtc(struct intel_crtc_state *state, int force_detach) ...@@ -4379,7 +4381,7 @@ int skl_update_scaler_crtc(struct intel_crtc_state *state, int force_detach)
DRM_DEBUG_KMS("Updating scaler for [CRTC:%i] scaler_user index %u.%u\n", 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); intel_crtc->base.base.id, intel_crtc->pipe, SKL_CRTC_INDEX);
return skl_update_scaler(state, force_detach, SKL_CRTC_INDEX, return skl_update_scaler(state, !state->base.active, SKL_CRTC_INDEX,
&state->scaler_state.scaler_id, DRM_ROTATE_0, &state->scaler_state.scaler_id, DRM_ROTATE_0,
state->pipe_src_w, state->pipe_src_h, state->pipe_src_w, state->pipe_src_h,
adjusted_mode->hdisplay, adjusted_mode->vdisplay); adjusted_mode->hdisplay, adjusted_mode->vdisplay);
...@@ -4453,7 +4455,15 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state, ...@@ -4453,7 +4455,15 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
return 0; return 0;
} }
static void skylake_pfit_update(struct intel_crtc *crtc, int enable) static void skylake_scaler_disable(struct intel_crtc *crtc)
{
int i;
for (i = 0; i < crtc->num_scalers; i++)
skl_detach_scaler(crtc, i);
}
static void skylake_pfit_enable(struct intel_crtc *crtc)
{ {
struct drm_device *dev = crtc->base.dev; struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
...@@ -4463,13 +4473,6 @@ static void skylake_pfit_update(struct intel_crtc *crtc, int enable) ...@@ -4463,13 +4473,6 @@ 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 */
skl_update_scaler_crtc(crtc->config, !enable);
intel_atomic_setup_scalers(crtc->base.dev, crtc, crtc->config);
skl_detach_scalers(crtc);
if (!enable)
return;
if (crtc->config->pch_pfit.enabled) { if (crtc->config->pch_pfit.enabled) {
int id; int id;
...@@ -4944,7 +4947,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) ...@@ -4944,7 +4947,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
intel_ddi_enable_pipe_clock(intel_crtc); intel_ddi_enable_pipe_clock(intel_crtc);
if (INTEL_INFO(dev)->gen == 9) if (INTEL_INFO(dev)->gen == 9)
skylake_pfit_update(intel_crtc, 1); skylake_pfit_enable(intel_crtc);
else if (INTEL_INFO(dev)->gen < 9) else if (INTEL_INFO(dev)->gen < 9)
ironlake_pfit_enable(intel_crtc); ironlake_pfit_enable(intel_crtc);
else else
...@@ -5081,7 +5084,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) ...@@ -5081,7 +5084,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder); intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder);
if (INTEL_INFO(dev)->gen == 9) if (INTEL_INFO(dev)->gen == 9)
skylake_pfit_update(intel_crtc, 0); skylake_scaler_disable(intel_crtc);
else if (INTEL_INFO(dev)->gen < 9) else if (INTEL_INFO(dev)->gen < 9)
ironlake_pfit_disable(intel_crtc); ironlake_pfit_disable(intel_crtc);
else else
...@@ -11834,7 +11837,17 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc, ...@@ -11834,7 +11837,17 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
return ret; return ret;
} }
return intel_atomic_setup_scalers(dev, intel_crtc, pipe_config); ret = 0;
if (INTEL_INFO(dev)->gen >= 9) {
if (mode_changed)
ret = skl_update_scaler_crtc(pipe_config);
if (!ret)
ret = intel_atomic_setup_scalers(dev, intel_crtc,
pipe_config);
}
return ret;
} }
static const struct drm_crtc_helper_funcs intel_helper_funcs = { static const struct drm_crtc_helper_funcs intel_helper_funcs = {
...@@ -15355,6 +15368,11 @@ static void readout_plane_state(struct intel_crtc *crtc, ...@@ -15355,6 +15368,11 @@ static void readout_plane_state(struct intel_crtc *crtc,
continue; continue;
drm_plane_state = p->base.state; drm_plane_state = p->base.state;
/* Plane scaler state is not touched here. The first atomic
* commit will restore all plane scalers to its old state.
*/
if (active && p->base.type == DRM_PLANE_TYPE_PRIMARY) { if (active && p->base.type == DRM_PLANE_TYPE_PRIMARY) {
visible = primary_get_hw_state(crtc); visible = primary_get_hw_state(crtc);
to_intel_plane_state(drm_plane_state)->visible = visible; to_intel_plane_state(drm_plane_state)->visible = visible;
......
...@@ -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_crtc(pipe_config, 0); ret = skl_update_scaler_crtc(pipe_config);
if (ret) if (ret)
return ret; return ret;
} }
......
...@@ -1149,7 +1149,7 @@ void intel_mode_from_pipe_config(struct drm_display_mode *mode, ...@@ -1149,7 +1149,7 @@ 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);
int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state, int force_detach); int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state);
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,
......
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