Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0519c102 authored by Ville Syrjälä's avatar Ville Syrjälä
Browse files

drm/i915: Implement display w/a #1143



Apparently SKL/KBL/CFL need some manual help to get the
programmed HDMI vswing to stick. Implement the relevant
workaround (display w/a #1143).

Note that the relevant chicken bits live in a transcoder register
even though the bits affect a specific DDI port rather than a
specific transcoder. Hence we must pick the correct transcoder
register instance based on the port rather than based on the
cpu_transcoder.

Also note that for completeness I included support for DDI A/E
in the code even though we never have HDMI on those ports.

v2: CFL needs the w/a as well (Rodrigo and Art)

Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Art Runyan <arthur.j.runyan@intel.com>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180122174131.28046-1-ville.syrjala@linux.intel.com


Reviewed-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
parent c19e1124
Loading
Loading
Loading
Loading
+6 −2
Original line number Original line Diff line number Diff line
@@ -7079,8 +7079,12 @@ enum {
#define CHICKEN_TRANS_A         0x420c0
#define CHICKEN_TRANS_A         0x420c0
#define CHICKEN_TRANS_B         0x420c4
#define CHICKEN_TRANS_B         0x420c4
#define CHICKEN_TRANS(trans) _MMIO_TRANS(trans, CHICKEN_TRANS_A, CHICKEN_TRANS_B)
#define CHICKEN_TRANS(trans) _MMIO_TRANS(trans, CHICKEN_TRANS_A, CHICKEN_TRANS_B)
#define PSR2_VSC_ENABLE_PROG_HEADER    (1<<12)
#define  DDI_TRAINING_OVERRIDE_ENABLE	(1<<19)
#define  DDI_TRAINING_OVERRIDE_VALUE	(1<<18)
#define  DDIE_TRAINING_OVERRIDE_ENABLE	(1<<17) /* CHICKEN_TRANS_A only */
#define  DDIE_TRAINING_OVERRIDE_VALUE	(1<<16) /* CHICKEN_TRANS_A only */
#define  PSR2_ADD_VERTICAL_LINE_COUNT   (1<<15)
#define  PSR2_ADD_VERTICAL_LINE_COUNT   (1<<15)
#define  PSR2_VSC_ENABLE_PROG_HEADER    (1<<12)


#define DISP_ARB_CTL	_MMIO(0x45000)
#define DISP_ARB_CTL	_MMIO(0x45000)
#define  DISP_FBC_MEMORY_WAKE		(1<<31)
#define  DISP_FBC_MEMORY_WAKE		(1<<31)
+42 −0
Original line number Original line Diff line number Diff line
@@ -2404,6 +2404,48 @@ static void intel_enable_ddi_hdmi(struct intel_encoder *encoder,
					  crtc_state->hdmi_high_tmds_clock_ratio,
					  crtc_state->hdmi_high_tmds_clock_ratio,
					  crtc_state->hdmi_scrambling);
					  crtc_state->hdmi_scrambling);


	/* Display WA #1143: skl,kbl,cfl */
	if (IS_GEN9_BC(dev_priv)) {
		/*
		 * For some reason these chicken bits have been
		 * stuffed into a transcoder register, event though
		 * the bits affect a specific DDI port rather than
		 * a specific transcoder.
		 */
		static const enum transcoder port_to_transcoder[] = {
			[PORT_A] = TRANSCODER_EDP,
			[PORT_B] = TRANSCODER_A,
			[PORT_C] = TRANSCODER_B,
			[PORT_D] = TRANSCODER_C,
			[PORT_E] = TRANSCODER_A,
		};
		enum transcoder transcoder = port_to_transcoder[port];
		u32 val;

		val = I915_READ(CHICKEN_TRANS(transcoder));

		if (port == PORT_E)
			val |= DDIE_TRAINING_OVERRIDE_ENABLE |
				DDIE_TRAINING_OVERRIDE_VALUE;
		else
			val |= DDI_TRAINING_OVERRIDE_ENABLE |
				DDI_TRAINING_OVERRIDE_VALUE;

		I915_WRITE(CHICKEN_TRANS(transcoder), val);
		POSTING_READ(CHICKEN_TRANS(transcoder));

		udelay(1);

		if (port == PORT_E)
			val &= ~(DDIE_TRAINING_OVERRIDE_ENABLE |
				 DDIE_TRAINING_OVERRIDE_VALUE);
		else
			val &= ~(DDI_TRAINING_OVERRIDE_ENABLE |
				 DDI_TRAINING_OVERRIDE_VALUE);

		I915_WRITE(CHICKEN_TRANS(transcoder), val);
	}

	/* In HDMI/DVI mode, the port width, and swing/emphasis values
	/* In HDMI/DVI mode, the port width, and swing/emphasis values
	 * are ignored so nothing special needs to be done besides
	 * are ignored so nothing special needs to be done besides
	 * enabling the port.
	 * enabling the port.