Skip to content

Commit

Permalink
drm/i915: Do not update pfit state when toggling crtc enabled.
Browse files Browse the repository at this point in the history
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: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
  • Loading branch information
Maarten Lankhorst authored and Daniel Vetter committed Jul 14, 2015
1 parent 8a75d15 commit e435d6e
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 38 deletions.
14 changes: 3 additions & 11 deletions drivers/gpu/drm/i915/intel_atomic.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,17 +272,12 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
struct drm_plane *plane = NULL;
struct intel_plane *intel_plane;
struct intel_plane_state *plane_state = NULL;
struct intel_crtc_scaler_state *scaler_state;
struct drm_atomic_state *drm_state;
struct intel_crtc_scaler_state *scaler_state =
&crtc_state->scaler_state;
struct drm_atomic_state *drm_state = crtc_state->base.state;
int num_scalers_need;
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);
DRM_DEBUG_KMS("crtc_state = %p need = %d avail = %d scaler_users = 0x%x\n",
crtc_state, num_scalers_need, intel_crtc->num_scalers,
Expand Down Expand Up @@ -326,9 +321,6 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
} else {
name = "PLANE";

if (!drm_state)
continue;

/* plane scaler case: assign as a plane scaler */
/* find the plane that set the bit as scaler_user */
plane = drm_state->planes[i];
Expand Down
68 changes: 43 additions & 25 deletions drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -2911,29 +2911,32 @@ unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
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
*/
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;
int i;

dev = intel_crtc->base.dev;
dev_priv = dev->dev_private;
scaler_state = &intel_crtc->config->scaler_state;

/* loop through and disable scalers that aren't in use */
for (i = 0; i < intel_crtc->num_scalers; i++) {
if (!scaler_state->scalers[i].in_use) {
I915_WRITE(SKL_PS_CTRL(intel_crtc->pipe, i), 0);
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);
}
if (!scaler_state->scalers[i].in_use)
skl_detach_scaler(intel_crtc, i);
}
}

Expand Down Expand Up @@ -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.
*
* @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)
int skl_update_scaler_crtc(struct intel_crtc_state *state)
{
struct intel_crtc *intel_crtc = to_intel_crtc(state->base.crtc);
struct drm_display_mode *adjusted_mode =
Expand All @@ -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",
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->pipe_src_w, state->pipe_src_h,
adjusted_mode->hdisplay, adjusted_mode->vdisplay);
Expand Down Expand Up @@ -4453,7 +4455,15 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
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_i915_private *dev_priv = dev->dev_private;
Expand All @@ -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);

/* 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) {
int id;

Expand Down Expand Up @@ -4944,7 +4947,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
intel_ddi_enable_pipe_clock(intel_crtc);

if (INTEL_INFO(dev)->gen == 9)
skylake_pfit_update(intel_crtc, 1);
skylake_pfit_enable(intel_crtc);
else if (INTEL_INFO(dev)->gen < 9)
ironlake_pfit_enable(intel_crtc);
else
Expand Down Expand Up @@ -5081,7 +5084,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder);

if (INTEL_INFO(dev)->gen == 9)
skylake_pfit_update(intel_crtc, 0);
skylake_scaler_disable(intel_crtc);
else if (INTEL_INFO(dev)->gen < 9)
ironlake_pfit_disable(intel_crtc);
else
Expand Down Expand Up @@ -11834,7 +11837,17 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
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 = {
Expand Down Expand Up @@ -15355,6 +15368,11 @@ static void readout_plane_state(struct intel_crtc *crtc,
continue;

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) {
visible = primary_get_hw_state(crtc);
to_intel_plane_state(drm_plane_state)->visible = visible;
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/intel_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1382,7 +1382,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,

if (INTEL_INFO(dev)->gen >= 9) {
int ret;
ret = skl_update_scaler_crtc(pipe_config, 0);
ret = skl_update_scaler_crtc(pipe_config);
if (ret)
return ret;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/intel_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_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);

unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
Expand Down

0 comments on commit e435d6e

Please sign in to comment.