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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/display/intel_lvds.c
Extension
.c
Size
29955 bytes
Lines
1016
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 intel_lvds_pps {
	struct intel_pps_delays delays;

	int divider;

	int port;
	bool powerdown_on_reset;
};

struct intel_lvds_encoder {
	struct intel_encoder base;

	bool is_dual_link;
	intel_reg_t reg;
	u32 a3_power;

	struct intel_lvds_pps init_pps;
	u32 init_lvds_val;

	struct intel_connector *attached_connector;
};

static struct intel_lvds_encoder *to_lvds_encoder(struct intel_encoder *encoder)
{
	return container_of(encoder, struct intel_lvds_encoder, base);
}

bool intel_lvds_port_enabled(struct intel_display *display,
			     intel_reg_t lvds_reg, enum pipe *pipe)
{
	u32 val;

	val = intel_de_read(display, lvds_reg);

	/* asserts want to know the pipe even if the port is disabled */
	if (HAS_PCH_CPT(display))
		*pipe = REG_FIELD_GET(LVDS_PIPE_SEL_MASK_CPT, val);
	else
		*pipe = REG_FIELD_GET(LVDS_PIPE_SEL_MASK, val);

	return val & LVDS_PORT_EN;
}

static bool intel_lvds_get_hw_state(struct intel_encoder *encoder,
				    enum pipe *pipe)
{
	struct intel_display *display = to_intel_display(encoder);
	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder);
	struct ref_tracker *wakeref;
	bool ret;

	wakeref = intel_display_power_get_if_enabled(display, encoder->power_domain);
	if (!wakeref)
		return false;

	ret = intel_lvds_port_enabled(display, lvds_encoder->reg, pipe);

	intel_display_power_put(display, encoder->power_domain, wakeref);

	return ret;
}

static void intel_lvds_get_config(struct intel_encoder *encoder,
				  struct intel_crtc_state *crtc_state)
{
	struct intel_display *display = to_intel_display(encoder);
	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder);
	u32 tmp, flags = 0;

	crtc_state->output_types |= BIT(INTEL_OUTPUT_LVDS);

	tmp = intel_de_read(display, lvds_encoder->reg);
	if (tmp & LVDS_HSYNC_POLARITY)
		flags |= DRM_MODE_FLAG_NHSYNC;
	else
		flags |= DRM_MODE_FLAG_PHSYNC;
	if (tmp & LVDS_VSYNC_POLARITY)
		flags |= DRM_MODE_FLAG_NVSYNC;
	else
		flags |= DRM_MODE_FLAG_PVSYNC;

	crtc_state->hw.adjusted_mode.flags |= flags;

	if (DISPLAY_VER(display) < 5)
		crtc_state->gmch_pfit.lvds_border_bits =
			tmp & LVDS_BORDER_ENABLE;

	/* gen2/3 store dither state in pfit control, needs to match */
	if (DISPLAY_VER(display) < 4) {
		tmp = intel_de_read(display, PFIT_CONTROL(display));

Annotation

Implementation Notes