Commit 0ef1905e authored by Ville Syrjälä's avatar Ville Syrjälä
Browse files

drm/i915: Introduce better global state handling



Our current global state handling is pretty ad-hoc. Let's try to
make it better by imitating the standard drm core private object
approach.

The reason why we don't want to directly use the private objects
is locking; Each private object has its own lock so if we
introduce any global private objects we get serialized by that
single lock across all pipes. The global state apporoach instead
uses a read/write lock type of approach where each individual
crtc lock counts as a read lock, and grabbing all the crtc locks
allows one write access.

Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200120174728.21095-15-ville.syrjala@linux.intel.com


Reviewed-by: default avatarImre Deak <imre.deak@intel.com>
parent 5f342993
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -190,6 +190,7 @@ i915-y += \
	display/intel_fbc.o \
	display/intel_fifo_underrun.o \
	display/intel_frontbuffer.o \
	display/intel_global_state.o \
	display/intel_hdcp.o \
	display/intel_hotplug.o \
	display/intel_lpe_audio.o \
+5 −2
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
#include "intel_atomic.h"
#include "intel_cdclk.h"
#include "intel_display_types.h"
#include "intel_global_state.h"
#include "intel_hdcp.h"
#include "intel_psr.h"
#include "intel_sprite.h"
@@ -502,6 +503,7 @@ void intel_atomic_state_free(struct drm_atomic_state *_state)
	struct intel_atomic_state *state = to_intel_atomic_state(_state);

	drm_atomic_state_default_release(&state->base);
	kfree(state->global_objs);

	i915_sw_fence_fini(&state->commit_ready);

@@ -513,6 +515,7 @@ void intel_atomic_state_clear(struct drm_atomic_state *s)
	struct intel_atomic_state *state = to_intel_atomic_state(s);

	drm_atomic_state_default_clear(&state->base);
	intel_atomic_clear_global_state(state);

	state->dpll_set = state->modeset = false;
	state->global_state_changed = false;
@@ -532,7 +535,7 @@ intel_atomic_get_crtc_state(struct drm_atomic_state *state,
	return to_intel_crtc_state(crtc_state);
}

int intel_atomic_lock_global_state(struct intel_atomic_state *state)
int _intel_atomic_lock_global_state(struct intel_atomic_state *state)
{
	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
	struct intel_crtc *crtc;
@@ -551,7 +554,7 @@ int intel_atomic_lock_global_state(struct intel_atomic_state *state)
	return 0;
}

int intel_atomic_serialize_global_state(struct intel_atomic_state *state)
int _intel_atomic_serialize_global_state(struct intel_atomic_state *state)
{
	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
	struct intel_crtc *crtc;
+2 −2
Original line number Diff line number Diff line
@@ -56,8 +56,8 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv,
			       struct intel_crtc *intel_crtc,
			       struct intel_crtc_state *crtc_state);

int intel_atomic_lock_global_state(struct intel_atomic_state *state);
int _intel_atomic_lock_global_state(struct intel_atomic_state *state);

int intel_atomic_serialize_global_state(struct intel_atomic_state *state);
int _intel_atomic_serialize_global_state(struct intel_atomic_state *state);

#endif /* __INTEL_ATOMIC_H__ */
+1 −1
Original line number Diff line number Diff line
@@ -829,7 +829,7 @@ retry:
		enable ? 2 * 96000 : 0;

	/* Protects dev_priv->cdclk.force_min_cdclk */
	ret = intel_atomic_lock_global_state(to_intel_atomic_state(state));
	ret = _intel_atomic_lock_global_state(to_intel_atomic_state(state));
	if (!ret)
		ret = drm_atomic_commit(state);

+4 −4
Original line number Diff line number Diff line
@@ -2080,7 +2080,7 @@ static int intel_compute_min_cdclk(struct intel_atomic_state *state)

		cdclk_state->min_cdclk[i] = min_cdclk;

		ret = intel_atomic_lock_global_state(state);
		ret = _intel_atomic_lock_global_state(state);
		if (ret)
			return ret;
	}
@@ -2128,7 +2128,7 @@ static int bxt_compute_min_voltage_level(struct intel_atomic_state *state)

		cdclk_state->min_voltage_level[i] = min_voltage_level;

		ret = intel_atomic_lock_global_state(state);
		ret = _intel_atomic_lock_global_state(state);
		if (ret)
			return ret;
	}
@@ -2403,12 +2403,12 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
		 * Also serialize commits across all crtcs
		 * if the actual hw needs to be poked.
		 */
		ret = intel_atomic_serialize_global_state(state);
		ret = _intel_atomic_serialize_global_state(state);
		if (ret)
			return ret;
	} else if (intel_cdclk_changed(&old_cdclk_state->logical,
				       &new_cdclk_state->logical)) {
		ret = intel_atomic_lock_global_state(state);
		ret = _intel_atomic_lock_global_state(state);
		if (ret)
			return ret;
	} else {
Loading