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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/display/intel_cmtg.c
Extension
.c
Size
6009 bytes
Lines
188
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_cmtg_config {
	bool cmtg_a_enable;
	/*
	 * Xe2_LPD adds a second CMTG that can be used for dual eDP async mode.
	 */
	bool cmtg_b_enable;
	bool trans_a_secondary;
	bool trans_b_secondary;
};

static bool intel_cmtg_has_cmtg_b(struct intel_display *display)
{
	return DISPLAY_VER(display) >= 20;
}

static bool intel_cmtg_has_clock_sel(struct intel_display *display)
{
	return DISPLAY_VER(display) >= 14;
}

static void intel_cmtg_dump_config(struct intel_display *display,
				   struct intel_cmtg_config *cmtg_config)
{
	drm_dbg_kms(display->drm,
		    "CMTG readout: CMTG A: %s, CMTG B: %s, Transcoder A secondary: %s, Transcoder B secondary: %s\n",
		    str_enabled_disabled(cmtg_config->cmtg_a_enable),
		    intel_cmtg_has_cmtg_b(display) ? str_enabled_disabled(cmtg_config->cmtg_b_enable) : "n/a",
		    str_yes_no(cmtg_config->trans_a_secondary),
		    str_yes_no(cmtg_config->trans_b_secondary));
}

static bool intel_cmtg_transcoder_is_secondary(struct intel_display *display,
					       enum transcoder trans)
{
	enum intel_display_power_domain power_domain;
	u32 val = 0;

	if (!HAS_TRANSCODER(display, trans))
		return false;

	power_domain = POWER_DOMAIN_TRANSCODER(trans);

	with_intel_display_power_if_enabled(display, power_domain)
		val = intel_de_read(display, TRANS_DDI_FUNC_CTL2(display, trans));

	return val & CMTG_SECONDARY_MODE;
}

static void intel_cmtg_get_config(struct intel_display *display,
				  struct intel_cmtg_config *cmtg_config)
{
	u32 val;

	val = intel_de_read(display, TRANS_CMTG_CTL_A);
	cmtg_config->cmtg_a_enable = val & CMTG_ENABLE;

	if (intel_cmtg_has_cmtg_b(display)) {
		val = intel_de_read(display, TRANS_CMTG_CTL_B);
		cmtg_config->cmtg_b_enable = val & CMTG_ENABLE;
	}

	cmtg_config->trans_a_secondary = intel_cmtg_transcoder_is_secondary(display, TRANSCODER_A);
	cmtg_config->trans_b_secondary = intel_cmtg_transcoder_is_secondary(display, TRANSCODER_B);
}

static bool intel_cmtg_disable_requires_modeset(struct intel_display *display,
						struct intel_cmtg_config *cmtg_config)
{
	if (DISPLAY_VER(display) >= 20)
		return false;

	return cmtg_config->trans_a_secondary || cmtg_config->trans_b_secondary;
}

static void intel_cmtg_disable(struct intel_display *display,
			       struct intel_cmtg_config *cmtg_config)
{
	u32 clk_sel_clr = 0;
	u32 clk_sel_set = 0;

	if (cmtg_config->trans_a_secondary)
		intel_de_rmw(display, TRANS_DDI_FUNC_CTL2(display, TRANSCODER_A),
			     CMTG_SECONDARY_MODE, 0);

	if (cmtg_config->trans_b_secondary)
		intel_de_rmw(display, TRANS_DDI_FUNC_CTL2(display, TRANSCODER_B),
			     CMTG_SECONDARY_MODE, 0);

	if (cmtg_config->cmtg_a_enable) {
		drm_dbg_kms(display->drm, "Disabling CMTG A\n");

Annotation

Implementation Notes