drivers/gpu/drm/i915/display/intel_display.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/i915/display/intel_display.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/display/intel_display.c
Extension
.c
Size
256570 bytes
Lines
8459
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (new_crtc_state->has_pch_encoder) {
			/* if driving the PCH, we need FDI enabled */
			assert_fdi_rx_pll_enabled(display,
						  intel_crtc_pch_transcoder(crtc));
			assert_fdi_tx_pll_enabled(display,
						  (enum pipe) cpu_transcoder);
		}
		/* FIXME: assert CPU port conditions for SNB+ */
	}

	/* Wa_22012358565:adl-p */
	if (intel_display_wa(display, INTEL_DISPLAY_WA_22012358565))
		intel_de_rmw(display, PIPE_ARB_CTL(display, pipe),
			     0, PIPE_ARB_USE_PROG_SLOTS);

	if (DISPLAY_VER(display) >= 14) {
		u32 clear = DP_DSC_INSERT_SF_AT_EOL_WA;
		u32 set = 0;

		if (DISPLAY_VER(display) == 14)
			set |= DP_FEC_BS_JITTER_WA;

		intel_de_rmw(display, CHICKEN_TRANS(display, cpu_transcoder),
			     clear, set);
	}

	val = intel_de_read(display, TRANSCONF(display, cpu_transcoder));
	if (val & TRANSCONF_ENABLE) {
		/* we keep both pipes enabled on 830 */
		drm_WARN_ON(display->drm, !display->platform.i830);
		return;
	}

	/* Wa_1409098942:adlp+ */
	if (DISPLAY_VER(display) >= 13 &&
	    new_crtc_state->dsc.compression_enable) {
		val &= ~TRANSCONF_PIXEL_COUNT_SCALING_MASK;
		val |= REG_FIELD_PREP(TRANSCONF_PIXEL_COUNT_SCALING_MASK,
				      TRANSCONF_PIXEL_COUNT_SCALING_X4);
	}

	intel_de_write(display, TRANSCONF(display, cpu_transcoder),
		       val | TRANSCONF_ENABLE);
	intel_de_posting_read(display, TRANSCONF(display, cpu_transcoder));

	/*
	 * Until the pipe starts PIPEDSL reads will return a stale value,
	 * which causes an apparent vblank timestamp jump when PIPEDSL
	 * resets to its proper value. That also messes up the frame count
	 * when it's derived from the timestamps. So let's wait for the
	 * pipe to start properly before we call drm_crtc_vblank_on()
	 */
	if (intel_crtc_max_vblank_count(new_crtc_state) == 0)
		intel_wait_for_pipe_scanline_moving(crtc);
}

void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state)
{
	struct intel_display *display = to_intel_display(old_crtc_state);
	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
	enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder;
	enum pipe pipe = crtc->pipe;
	u32 val;

	drm_dbg_kms(display->drm, "disabling pipe %c\n", pipe_name(pipe));

	/*
	 * Make sure planes won't keep trying to pump pixels to us,
	 * or we might hang the display.
	 */
	assert_planes_disabled(crtc);

	val = intel_de_read(display, TRANSCONF(display, cpu_transcoder));
	if ((val & TRANSCONF_ENABLE) == 0)
		return;

	/*
	 * Double wide has implications for planes
	 * so best keep it disabled when not needed.
	 */
	if (old_crtc_state->double_wide)
		val &= ~TRANSCONF_DOUBLE_WIDE;

	/* Don't disable pipe or pipe PLLs if needed */
	if (!display->platform.i830)
		val &= ~TRANSCONF_ENABLE;

	/* Wa_1409098942:adlp+ */
	if (DISPLAY_VER(display) >= 13 &&
	    old_crtc_state->dsc.compression_enable)

Annotation

Implementation Notes