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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/display/intel_pps.c
Extension
.c
Size
54984 bytes
Lines
1874
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

struct pps_registers {
	intel_reg_t pp_ctrl;
	intel_reg_t pp_stat;
	intel_reg_t pp_on;
	intel_reg_t pp_off;
	intel_reg_t pp_div;
};

static void intel_pps_get_registers(struct intel_dp *intel_dp,
				    struct pps_registers *regs)
{
	struct intel_display *display = to_intel_display(intel_dp);
	int pps_idx;

	memset(regs, 0, sizeof(*regs));

	if (display->platform.valleyview || display->platform.cherryview)
		pps_idx = vlv_power_sequencer_pipe(intel_dp);
	else if (display->platform.geminilake || display->platform.broxton)
		pps_idx = bxt_power_sequencer_idx(intel_dp);
	else
		pps_idx = intel_dp->pps.pps_idx;

	regs->pp_ctrl = PP_CONTROL(display, pps_idx);
	regs->pp_stat = PP_STATUS(display, pps_idx);
	regs->pp_on = PP_ON_DELAYS(display, pps_idx);
	regs->pp_off = PP_OFF_DELAYS(display, pps_idx);

	/* Cycle delay moved from PP_DIVISOR to PP_CONTROL */
	if (display->platform.geminilake || display->platform.broxton ||
	    INTEL_PCH_TYPE(display) >= PCH_CNP)
		regs->pp_div = INVALID_MMIO_REG;
	else
		regs->pp_div = PP_DIVISOR(display, pps_idx);
}

static intel_reg_t
_pp_ctrl_reg(struct intel_dp *intel_dp)
{
	struct pps_registers regs;

	intel_pps_get_registers(intel_dp, &regs);

	return regs.pp_ctrl;
}

static intel_reg_t
_pp_stat_reg(struct intel_dp *intel_dp)
{
	struct pps_registers regs;

	intel_pps_get_registers(intel_dp, &regs);

	return regs.pp_stat;
}

static bool edp_have_panel_power(struct intel_dp *intel_dp)
{
	struct intel_display *display = to_intel_display(intel_dp);

	lockdep_assert_held(&display->pps.mutex);

	if ((display->platform.valleyview || display->platform.cherryview) &&
	    intel_dp->pps.vlv_pps_pipe == INVALID_PIPE)
		return false;

	return (intel_de_read(display, _pp_stat_reg(intel_dp)) & PP_ON) != 0;
}

static bool edp_have_panel_vdd(struct intel_dp *intel_dp)
{
	struct intel_display *display = to_intel_display(intel_dp);

	lockdep_assert_held(&display->pps.mutex);

	if ((display->platform.valleyview || display->platform.cherryview) &&
	    intel_dp->pps.vlv_pps_pipe == INVALID_PIPE)
		return false;

	return intel_de_read(display, _pp_ctrl_reg(intel_dp)) & EDP_FORCE_VDD;
}

void intel_pps_check_power_unlocked(struct intel_dp *intel_dp)
{
	struct intel_display *display = to_intel_display(intel_dp);
	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);

	if (!intel_dp_is_edp(intel_dp))
		return;

Annotation

Implementation Notes