Commit 08db6652 authored by Damien Lespiau's avatar Damien Lespiau Committed by Daniel Vetter
Browse files

drm/i915/skl: Check the DDB state at modeset



v2: Don't check DDB on pre-SKL platforms
    Don't check DDB state on disabled pipes

v3: Squash "Expose skl_ddb_get_hw_state()"

Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: default avatarDamien Lespiau <damien.lespiau@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent c5511e44
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -1400,6 +1400,15 @@ static inline uint16_t skl_ddb_entry_size(const struct skl_ddb_entry *entry)
	return entry->end - entry->start + 1;
}

static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1,
				       const struct skl_ddb_entry *e2)
{
	if (e1->start == e2->start && e1->end == e2->end)
		return true;

	return false;
}

struct skl_ddb_allocation {
	struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES];
	struct skl_ddb_entry cursor[I915_MAX_PIPES];
+51 −0
Original line number Diff line number Diff line
@@ -10511,6 +10511,56 @@ intel_pipe_config_compare(struct drm_device *dev,
	return true;
}

static void check_wm_state(struct drm_device *dev)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct skl_ddb_allocation hw_ddb, *sw_ddb;
	struct intel_crtc *intel_crtc;
	int plane;

	if (INTEL_INFO(dev)->gen < 9)
		return;

	skl_ddb_get_hw_state(dev_priv, &hw_ddb);
	sw_ddb = &dev_priv->wm.skl_hw.ddb;

	for_each_intel_crtc(dev, intel_crtc) {
		struct skl_ddb_entry *hw_entry, *sw_entry;
		const enum pipe pipe = intel_crtc->pipe;

		if (!intel_crtc->active)
			continue;

		/* planes */
		for_each_plane(pipe, plane) {
			hw_entry = &hw_ddb.plane[pipe][plane];
			sw_entry = &sw_ddb->plane[pipe][plane];

			if (skl_ddb_entry_equal(hw_entry, sw_entry))
				continue;

			DRM_ERROR("mismatch in DDB state pipe %c plane %d "
				  "(expected (%u,%u), found (%u,%u))\n",
				  pipe_name(pipe), plane + 1,
				  sw_entry->start, sw_entry->end,
				  hw_entry->start, hw_entry->end);
		}

		/* cursor */
		hw_entry = &hw_ddb.cursor[pipe];
		sw_entry = &sw_ddb->cursor[pipe];

		if (skl_ddb_entry_equal(hw_entry, sw_entry))
			continue;

		DRM_ERROR("mismatch in DDB state pipe %c cursor "
			  "(expected (%u,%u), found (%u,%u))\n",
			  pipe_name(pipe),
			  sw_entry->start, sw_entry->end,
			  hw_entry->start, hw_entry->end);
	}
}

static void
check_connector_state(struct drm_device *dev)
{
@@ -10710,6 +10760,7 @@ check_shared_dpll_state(struct drm_device *dev)
void
intel_modeset_check_state(struct drm_device *dev)
{
	check_wm_state(dev);
	check_connector_state(dev);
	check_encoder_state(dev);
	check_crtc_state(dev);
+2 −0
Original line number Diff line number Diff line
@@ -1165,6 +1165,8 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv);
void gen6_rps_boost(struct drm_i915_private *dev_priv);
void ilk_wm_get_hw_state(struct drm_device *dev);
void skl_wm_get_hw_state(struct drm_device *dev);
void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
			  struct skl_ddb_allocation *ddb /* out */);


/* intel_sdvo.c */
+2 −2
Original line number Diff line number Diff line
@@ -3057,7 +3057,7 @@ static void skl_ddb_entry_init_from_hw(struct skl_ddb_entry *entry, u32 reg)
	entry->end = (reg >> 16) & 0x3ff;
}

static void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
			  struct skl_ddb_allocation *ddb /* out */)
{
	struct drm_device *dev = dev_priv->dev;