Commit 3af2ff08 authored by Imre Deak's avatar Imre Deak
Browse files

drm/i915: Enable a PIPEDMC whenever its corresponding pipe is enabled



Make sure that PIPEDMCs are enabled whenever the corresponding pipe is
enabled.

This is required at least by the latest ADLP v2.18 firmware, which adds
a new handler enabled by default and running whenever the pipe is
enabled at the vertical referesh rate.

Bspec: 50344, 67620

Signed-off-by: default avatarImre Deak <imre.deak@intel.com>
Reviewed-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
Tested-by: default avatarGustavo Sousa <gustavo.sousa@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230102183324.862279-1-imre.deak@intel.com
parent fdbc5aeb
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -1867,6 +1867,8 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
	if (drm_WARN_ON(&dev_priv->drm, crtc->active))
		return;

	intel_dmc_enable_pipe(dev_priv, crtc->pipe);

	if (!new_crtc_state->bigjoiner_pipes) {
		intel_encoders_pre_pll_enable(state, crtc);

@@ -2002,6 +2004,7 @@ static void hsw_crtc_disable(struct intel_atomic_state *state,
{
	const struct intel_crtc_state *old_crtc_state =
		intel_atomic_get_old_crtc_state(state, crtc);
	struct drm_i915_private *i915 = to_i915(crtc->base.dev);

	/*
	 * FIXME collapse everything to one hook.
@@ -2011,6 +2014,8 @@ static void hsw_crtc_disable(struct intel_atomic_state *state,
		intel_encoders_disable(state, crtc);
		intel_encoders_post_disable(state, crtc);
	}

	intel_dmc_disable_pipe(i915, crtc->pipe);
}

static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state)
+24 −0
Original line number Diff line number Diff line
@@ -97,6 +97,8 @@ MODULE_FIRMWARE(BXT_DMC_PATH);
#define DMC_V3_MAX_MMIO_COUNT		20
#define DMC_V1_MMIO_START_RANGE		0x80000

#define PIPE_TO_DMC_ID(pipe)		 (DMC_FW_PIPEA + ((pipe) - PIPE_A))

struct intel_css_header {
	/* 0x09 for DMC */
	u32 module_type;
@@ -396,6 +398,28 @@ static void pipedmc_clock_gating_wa(struct drm_i915_private *i915, bool enable)
				     PIPEDMC_GATING_DIS, 0);
}

void intel_dmc_enable_pipe(struct drm_i915_private *i915, enum pipe pipe)
{
	if (!has_dmc_id_fw(i915, PIPE_TO_DMC_ID(pipe)))
		return;

	if (DISPLAY_VER(i915) >= 14)
		intel_de_rmw(i915, MTL_PIPEDMC_CONTROL, 0, PIPEDMC_ENABLE_MTL(pipe));
	else
		intel_de_rmw(i915, PIPEDMC_CONTROL(pipe), 0, PIPEDMC_ENABLE);
}

void intel_dmc_disable_pipe(struct drm_i915_private *i915, enum pipe pipe)
{
	if (!has_dmc_id_fw(i915, PIPE_TO_DMC_ID(pipe)))
		return;

	if (DISPLAY_VER(i915) >= 14)
		intel_de_rmw(i915, MTL_PIPEDMC_CONTROL, PIPEDMC_ENABLE_MTL(pipe), 0);
	else
		intel_de_rmw(i915, PIPEDMC_CONTROL(pipe), PIPEDMC_ENABLE, 0);
}

/**
 * intel_dmc_load_program() - write the firmware from memory to register.
 * @dev_priv: i915 drm device.
+4 −0
Original line number Diff line number Diff line
@@ -13,6 +13,8 @@
struct drm_i915_error_state_buf;
struct drm_i915_private;

enum pipe;

enum {
	DMC_FW_MAIN = 0,
	DMC_FW_PIPEA,
@@ -47,6 +49,8 @@ struct intel_dmc {
void intel_dmc_ucode_init(struct drm_i915_private *i915);
void intel_dmc_load_program(struct drm_i915_private *i915);
void intel_dmc_disable_program(struct drm_i915_private *i915);
void intel_dmc_enable_pipe(struct drm_i915_private *i915, enum pipe pipe);
void intel_dmc_disable_pipe(struct drm_i915_private *i915, enum pipe pipe);
void intel_dmc_ucode_fini(struct drm_i915_private *i915);
void intel_dmc_ucode_suspend(struct drm_i915_private *i915);
void intel_dmc_ucode_resume(struct drm_i915_private *i915);
+10 −0
Original line number Diff line number Diff line
@@ -11,6 +11,16 @@
#define DMC_PROGRAM(addr, i)	_MMIO((addr) + (i) * 4)
#define DMC_SSP_BASE_ADDR_GEN9	0x00002FC0

#define _PIPEDMC_CONTROL_A		0x45250
#define _PIPEDMC_CONTROL_B		0x45254
#define PIPEDMC_CONTROL(pipe)		_MMIO_PIPE(pipe, \
						   _PIPEDMC_CONTROL_A, \
						   _PIPEDMC_CONTROL_B)
#define  PIPEDMC_ENABLE			REG_BIT(0)

#define MTL_PIPEDMC_CONTROL		_MMIO(0x45250)
#define  PIPEDMC_ENABLE_MTL(pipe)	REG_BIT(((pipe) - PIPE_A) * 4)

#define _ADLP_PIPEDMC_REG_MMIO_BASE_A	0x5f000
#define _TGL_PIPEDMC_REG_MMIO_BASE_A	0x92000

+3 −1
Original line number Diff line number Diff line
@@ -698,9 +698,11 @@ void intel_modeset_setup_hw_state(struct drm_i915_private *i915,

		drm_crtc_vblank_reset(&crtc->base);

		if (crtc_state->hw.active)
		if (crtc_state->hw.active) {
			intel_dmc_enable_pipe(i915, crtc->pipe);
			intel_crtc_vblank_on(crtc_state);
		}
	}

	intel_fbc_sanitize(i915);