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

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

File Facts

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

for_each_dsi_port(port, intel_dsi->ports) {
			intel_de_write(display, ADL_MIPIO_DW(port, 8),
				       esc_clk_div_m_phy & TX_ESC_CLK_DIV_PHY);
			intel_de_posting_read(display, ADL_MIPIO_DW(port, 8));
		}
	}
}

static void get_dsi_io_power_domains(struct intel_dsi *intel_dsi)
{
	struct intel_display *display = to_intel_display(&intel_dsi->base);
	enum port port;

	for_each_dsi_port(port, intel_dsi->ports) {
		drm_WARN_ON(display->drm, intel_dsi->io_wakeref[port]);
		intel_dsi->io_wakeref[port] =
			intel_display_power_get(display,
						port == PORT_A ?
						POWER_DOMAIN_PORT_DDI_IO_A :
						POWER_DOMAIN_PORT_DDI_IO_B);
	}
}

static void gen11_dsi_enable_io_power(struct intel_encoder *encoder)
{
	struct intel_display *display = to_intel_display(encoder);
	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
	enum port port;

	for_each_dsi_port(port, intel_dsi->ports)
		intel_de_rmw(display, ICL_DSI_IO_MODECTL(port),
			     0, COMBO_PHY_MODE_DSI);

	get_dsi_io_power_domains(intel_dsi);
}

static void gen11_dsi_power_up_lanes(struct intel_encoder *encoder)
{
	struct intel_display *display = to_intel_display(encoder);
	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
	enum phy phy;

	for_each_dsi_phy(phy, intel_dsi->phys)
		intel_combo_phy_power_up_lanes(display, phy, true,
					       intel_dsi->lane_count, false);
}

static void gen11_dsi_config_phy_lanes_sequence(struct intel_encoder *encoder)
{
	struct intel_display *display = to_intel_display(encoder);
	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
	enum phy phy;
	u32 tmp;
	int lane;

	/* Step 4b(i) set loadgen select for transmit and aux lanes */
	for_each_dsi_phy(phy, intel_dsi->phys) {
		intel_de_rmw(display, ICL_PORT_TX_DW4_AUX(phy),
			     LOADGEN_SELECT, 0);
		for (lane = 0; lane <= 3; lane++)
			intel_de_rmw(display, ICL_PORT_TX_DW4_LN(lane, phy),
				     LOADGEN_SELECT, lane != 2 ? LOADGEN_SELECT : 0);
	}

	/* Step 4b(ii) set latency optimization for transmit and aux lanes */
	for_each_dsi_phy(phy, intel_dsi->phys) {
		intel_de_rmw(display, ICL_PORT_TX_DW2_AUX(phy),
			     FRC_LATENCY_OPTIM_MASK, FRC_LATENCY_OPTIM_VAL(0x5));
		tmp = intel_de_read(display, ICL_PORT_TX_DW2_LN(0, phy));
		tmp &= ~FRC_LATENCY_OPTIM_MASK;
		tmp |= FRC_LATENCY_OPTIM_VAL(0x5);
		intel_de_write(display, ICL_PORT_TX_DW2_GRP(phy), tmp);

		/* For EHL, TGL, set latency optimization for PCS_DW1 lanes */
		if (display->platform.jasperlake || display->platform.elkhartlake ||
		    (DISPLAY_VER(display) >= 12)) {
			intel_de_rmw(display, ICL_PORT_PCS_DW1_AUX(phy),
				     LATENCY_OPTIM_MASK, LATENCY_OPTIM_VAL(0));

			tmp = intel_de_read(display,
					    ICL_PORT_PCS_DW1_LN(0, phy));
			tmp &= ~LATENCY_OPTIM_MASK;
			tmp |= LATENCY_OPTIM_VAL(0x1);
			intel_de_write(display, ICL_PORT_PCS_DW1_GRP(phy),
				       tmp);
		}
	}

}

Annotation

Implementation Notes