Commit 0e6e0be4 authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915: Markup paired operations on display power domains



The majority of runtime-pm operations are bounded and scoped within a
function; these are easy to verify that the wakeref are handled
correctly. We can employ the compiler to help us, and reduce the number
of wakerefs tracked when debugging, by passing around cookies provided
by the various rpm_get functions to their rpm_put counterpart. This
makes the pairing explicit, and given the required wakeref cookie the
compiler can verify that we pass an initialised value to the rpm_put
(quite handy for double checking error paths).

Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: default avatarMika Kuoppala <mika.kuoppala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190114142129.24398-16-chris@chris-wilson.co.uk
parent d4225a53
Loading
Loading
Loading
Loading
+20 −15
Original line number Diff line number Diff line
@@ -626,10 +626,12 @@ static void gen8_display_interrupt_info(struct seq_file *m)

	for_each_pipe(dev_priv, pipe) {
		enum intel_display_power_domain power_domain;
		intel_wakeref_t wakeref;

		power_domain = POWER_DOMAIN_PIPE(pipe);
		if (!intel_display_power_get_if_enabled(dev_priv,
							power_domain)) {
		wakeref = intel_display_power_get_if_enabled(dev_priv,
							     power_domain);
		if (!wakeref) {
			seq_printf(m, "Pipe %c power disabled\n",
				   pipe_name(pipe));
			continue;
@@ -644,7 +646,7 @@ static void gen8_display_interrupt_info(struct seq_file *m)
			   pipe_name(pipe),
			   I915_READ(GEN8_DE_PIPE_IER(pipe)));

		intel_display_power_put(dev_priv, power_domain);
		intel_display_power_put(dev_priv, power_domain, wakeref);
	}

	seq_printf(m, "Display Engine port interrupt mask:\t%08x\n",
@@ -680,6 +682,8 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
	wakeref = intel_runtime_pm_get(dev_priv);

	if (IS_CHERRYVIEW(dev_priv)) {
		intel_wakeref_t pref;

		seq_printf(m, "Master Interrupt Control:\t%08x\n",
			   I915_READ(GEN8_MASTER_IRQ));

@@ -695,8 +699,9 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
			enum intel_display_power_domain power_domain;

			power_domain = POWER_DOMAIN_PIPE(pipe);
			if (!intel_display_power_get_if_enabled(dev_priv,
								power_domain)) {
			pref = intel_display_power_get_if_enabled(dev_priv,
								  power_domain);
			if (!pref) {
				seq_printf(m, "Pipe %c power disabled\n",
					   pipe_name(pipe));
				continue;
@@ -706,17 +711,17 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
				   pipe_name(pipe),
				   I915_READ(PIPESTAT(pipe)));

			intel_display_power_put(dev_priv, power_domain);
			intel_display_power_put(dev_priv, power_domain, pref);
		}

		intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
		pref = intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
		seq_printf(m, "Port hotplug:\t%08x\n",
			   I915_READ(PORT_HOTPLUG_EN));
		seq_printf(m, "DPFLIPSTAT:\t%08x\n",
			   I915_READ(VLV_DPFLIPSTAT));
		seq_printf(m, "DPINVGTT:\t%08x\n",
			   I915_READ(DPINVGTT));
		intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
		intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, pref);

		for (i = 0; i < 4; i++) {
			seq_printf(m, "GT Interrupt IMR %d:\t%08x\n",
@@ -779,10 +784,12 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
			   I915_READ(VLV_IMR));
		for_each_pipe(dev_priv, pipe) {
			enum intel_display_power_domain power_domain;
			intel_wakeref_t pref;

			power_domain = POWER_DOMAIN_PIPE(pipe);
			if (!intel_display_power_get_if_enabled(dev_priv,
								power_domain)) {
			pref = intel_display_power_get_if_enabled(dev_priv,
								  power_domain);
			if (!pref) {
				seq_printf(m, "Pipe %c power disabled\n",
					   pipe_name(pipe));
				continue;
@@ -791,7 +798,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
			seq_printf(m, "Pipe %c stat:\t%08x\n",
				   pipe_name(pipe),
				   I915_READ(PIPESTAT(pipe)));
			intel_display_power_put(dev_priv, power_domain);
			intel_display_power_put(dev_priv, power_domain, pref);
		}

		seq_printf(m, "Master IER:\t%08x\n",
@@ -1709,8 +1716,7 @@ static int i915_sr_status(struct seq_file *m, void *unused)
	intel_wakeref_t wakeref;
	bool sr_enabled = false;

	wakeref = intel_runtime_pm_get(dev_priv);
	intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
	wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);

	if (INTEL_GEN(dev_priv) >= 9)
		/* no global SR status; inspect per-plane WM */;
@@ -1726,8 +1732,7 @@ static int i915_sr_status(struct seq_file *m, void *unused)
	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
		sr_enabled = I915_READ(FW_BLC_SELF_VLV) & FW_CSPWRDWNEN;

	intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
	intel_runtime_pm_put(dev_priv, wakeref);
	intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, wakeref);

	seq_printf(m, "self-refresh: %s\n", enableddisabled(sr_enabled));

+2 −0
Original line number Diff line number Diff line
@@ -344,6 +344,7 @@ struct intel_csr {
	uint32_t mmiodata[8];
	uint32_t dc_state;
	uint32_t allowed_dc_mask;
	intel_wakeref_t wakeref;
};

enum i915_cache_level {
@@ -1982,6 +1983,7 @@ struct drm_i915_private {
		 * is a slight delay before we do so.
		 */
		intel_wakeref_t awake;
		intel_wakeref_t power;

		/**
		 * The number of times we have woken up.
+2 −2
Original line number Diff line number Diff line
@@ -176,7 +176,7 @@ static u32 __i915_gem_park(struct drm_i915_private *i915)
	if (INTEL_GEN(i915) >= 6)
		gen6_rps_idle(i915);

	intel_display_power_put(i915, POWER_DOMAIN_GT_IRQ);
	intel_display_power_put(i915, POWER_DOMAIN_GT_IRQ, i915->gt.power);

	intel_runtime_pm_put(i915, wakeref);

@@ -221,7 +221,7 @@ void i915_gem_unpark(struct drm_i915_private *i915)
	 * Work around it by grabbing a GT IRQ power domain whilst there is any
	 * GT activity, preventing any DC state transitions.
	 */
	intel_display_power_get(i915, POWER_DOMAIN_GT_IRQ);
	i915->gt.power = intel_display_power_get(i915, POWER_DOMAIN_GT_IRQ);

	if (unlikely(++i915->gt.epoch == 0)) /* keep 0 as invalid */
		i915->gt.epoch = 1;
+24 −12
Original line number Diff line number Diff line
@@ -337,7 +337,9 @@ static void gen11_dsi_enable_io_power(struct intel_encoder *encoder)
	}

	for_each_dsi_port(port, intel_dsi->ports) {
		intel_display_power_get(dev_priv, port == PORT_A ?
		intel_dsi->io_wakeref[port] =
			intel_display_power_get(dev_priv,
						port == PORT_A ?
						POWER_DOMAIN_PORT_DDI_A_IO :
						POWER_DOMAIN_PORT_DDI_B_IO);
	}
@@ -1125,10 +1127,18 @@ static void gen11_dsi_disable_io_power(struct intel_encoder *encoder)
	enum port port;
	u32 tmp;

	intel_display_power_put(dev_priv, POWER_DOMAIN_PORT_DDI_A_IO);
	for_each_dsi_port(port, intel_dsi->ports) {
		intel_wakeref_t wakeref;

	if (intel_dsi->dual_link)
		intel_display_power_put(dev_priv, POWER_DOMAIN_PORT_DDI_B_IO);
		wakeref = fetch_and_zero(&intel_dsi->io_wakeref[port]);
		if (wakeref) {
			intel_display_power_put(dev_priv,
						port == PORT_A ?
						POWER_DOMAIN_PORT_DDI_A_IO :
						POWER_DOMAIN_PORT_DDI_B_IO,
						wakeref);
		}
	}

	/* set mode to DDI */
	for_each_dsi_port(port, intel_dsi->ports) {
@@ -1229,13 +1239,15 @@ static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder,
{
	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
	u32 tmp;
	enum port port;
	enum transcoder dsi_trans;
	intel_wakeref_t wakeref;
	enum port port;
	bool ret = false;
	u32 tmp;

	if (!intel_display_power_get_if_enabled(dev_priv,
						encoder->power_domain))
	wakeref = intel_display_power_get_if_enabled(dev_priv,
						     encoder->power_domain);
	if (!wakeref)
		return false;

	for_each_dsi_port(port, intel_dsi->ports) {
@@ -1260,7 +1272,7 @@ static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder,
		ret = tmp & PIPECONF_ENABLE;
	}
out:
	intel_display_power_put(dev_priv, encoder->power_domain);
	intel_display_power_put(dev_priv, encoder->power_domain, wakeref);
	return ret;
}

+2 −1
Original line number Diff line number Diff line
@@ -748,7 +748,8 @@ static void i915_audio_component_get_power(struct device *kdev)

static void i915_audio_component_put_power(struct device *kdev)
{
	intel_display_power_put(kdev_to_i915(kdev), POWER_DOMAIN_AUDIO);
	intel_display_power_put_unchecked(kdev_to_i915(kdev),
					  POWER_DOMAIN_AUDIO);
}

static void i915_audio_component_codec_wake_override(struct device *kdev,
Loading