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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/display/intel_alpm.c
Extension
.c
Size
19478 bytes
Lines
648
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 (intel_dp->as_sdp_supported) {
			u32 pr_alpm_ctl = get_pr_alpm_as_sdp_transmission_time(crtc_state);

			if (crtc_state->link_off_after_as_sdp_when_pr_active)
				pr_alpm_ctl |= PR_ALPM_CTL_ALLOW_LINK_OFF_BETWEEN_AS_SDP_AND_SU;
			if (crtc_state->disable_as_sdp_when_pr_active)
				pr_alpm_ctl |= PR_ALPM_CTL_AS_SDP_TRANSMISSION_IN_ACTIVE_DISABLE;

			intel_de_write(display, PR_ALPM_CTL(display, cpu_transcoder),
				       pr_alpm_ctl);
		}

	} else {
		alpm_ctl = ALPM_CTL_EXTENDED_FAST_WAKE_ENABLE |
			ALPM_CTL_EXTENDED_FAST_WAKE_TIME(crtc_state->alpm_state.fast_wake_lines);
	}

	if (crtc_state->has_lobf) {
		alpm_ctl |= ALPM_CTL_LOBF_ENABLE;
		drm_dbg_kms(display->drm, "Link off between frames (LOBF) enabled\n");
	}

	alpm_ctl |= ALPM_CTL_ALPM_ENTRY_CHECK(crtc_state->alpm_state.check_entry_lines);

	intel_de_write(display, ALPM_CTL(display, cpu_transcoder), alpm_ctl);
	mutex_unlock(&intel_dp->alpm.lock);
}

void intel_alpm_configure(struct intel_dp *intel_dp,
			  const struct intel_crtc_state *crtc_state)
{
	lnl_alpm_configure(intel_dp, crtc_state);
	intel_dp->alpm.transcoder = crtc_state->cpu_transcoder;
}

void intel_alpm_port_configure(struct intel_dp *intel_dp,
			       const struct intel_crtc_state *crtc_state)
{
	struct intel_display *display = to_intel_display(intel_dp);
	enum port port = dp_to_dig_port(intel_dp)->base.port;
	u32 alpm_ctl_val = 0, lfps_ctl_val = 0;

	if (DISPLAY_VER(display) < 20)
		return;

	if (intel_alpm_is_alpm_aux_less(intel_dp, crtc_state)) {
		alpm_ctl_val = PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE |
			PORT_ALPM_CTL_MAX_PHY_SWING_SETUP(15) |
			PORT_ALPM_CTL_MAX_PHY_SWING_HOLD(0) |
			PORT_ALPM_CTL_SILENCE_PERIOD(
				crtc_state->alpm_state.silence_period_sym_clocks);
		lfps_ctl_val = PORT_ALPM_LFPS_CTL_LFPS_CYCLE_COUNT(LFPS_CYCLE_COUNT) |
			PORT_ALPM_LFPS_CTL_LFPS_HALF_CYCLE_DURATION(
				crtc_state->alpm_state.lfps_half_cycle_num_of_syms) |
			PORT_ALPM_LFPS_CTL_FIRST_LFPS_HALF_CYCLE_DURATION(
				crtc_state->alpm_state.lfps_half_cycle_num_of_syms) |
			PORT_ALPM_LFPS_CTL_LAST_LFPS_HALF_CYCLE_DURATION(
				crtc_state->alpm_state.lfps_half_cycle_num_of_syms);
	}

	intel_de_write(display, PORT_ALPM_CTL(port), alpm_ctl_val);

	intel_de_write(display, PORT_ALPM_LFPS_CTL(port), lfps_ctl_val);
}

void intel_alpm_lobf_disable(const struct intel_crtc_state *new_crtc_state)
{
	struct intel_display *display = to_intel_display(new_crtc_state);
	enum transcoder cpu_transcoder = new_crtc_state->cpu_transcoder;
	struct intel_encoder *encoder;

	for_each_intel_encoder_mask(display->drm, encoder,
				    new_crtc_state->uapi.encoder_mask) {
		struct intel_dp *intel_dp;

		if (!intel_encoder_is_dp(encoder))
			continue;

		intel_dp = enc_to_intel_dp(encoder);

		if (!intel_dp_is_edp(intel_dp))
			continue;

		mutex_lock(&intel_dp->alpm.lock);
		intel_de_write(display, ALPM_CTL(display, cpu_transcoder), 0);
		drm_dbg_kms(display->drm, "Link off between frames (LOBF) disabled\n");
		mutex_unlock(&intel_dp->alpm.lock);
	}
}

Annotation

Implementation Notes