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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/display/intel_display_power.c
Extension
.c
Size
78848 bytes
Lines
2582
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 buddy_page_mask {
	u32 page_mask;
	u8 type;
	u8 num_channels;
};

static const struct buddy_page_mask tgl_buddy_page_masks[] = {
	{ .num_channels = 1, .type = INTEL_DRAM_DDR4,   .page_mask = 0xF },
	{ .num_channels = 1, .type = INTEL_DRAM_DDR5,	.page_mask = 0xF },
	{ .num_channels = 2, .type = INTEL_DRAM_LPDDR4, .page_mask = 0x1C },
	{ .num_channels = 2, .type = INTEL_DRAM_LPDDR5, .page_mask = 0x1C },
	{ .num_channels = 2, .type = INTEL_DRAM_DDR4,   .page_mask = 0x1F },
	{ .num_channels = 2, .type = INTEL_DRAM_DDR5,   .page_mask = 0x1E },
	{ .num_channels = 4, .type = INTEL_DRAM_LPDDR4, .page_mask = 0x38 },
	{ .num_channels = 4, .type = INTEL_DRAM_LPDDR5, .page_mask = 0x38 },
	{}
};

static const struct buddy_page_mask wa_1409767108_buddy_page_masks[] = {
	{ .num_channels = 1, .type = INTEL_DRAM_LPDDR4, .page_mask = 0x1 },
	{ .num_channels = 1, .type = INTEL_DRAM_DDR4,   .page_mask = 0x1 },
	{ .num_channels = 1, .type = INTEL_DRAM_DDR5,   .page_mask = 0x1 },
	{ .num_channels = 1, .type = INTEL_DRAM_LPDDR5, .page_mask = 0x1 },
	{ .num_channels = 2, .type = INTEL_DRAM_LPDDR4, .page_mask = 0x3 },
	{ .num_channels = 2, .type = INTEL_DRAM_DDR4,   .page_mask = 0x3 },
	{ .num_channels = 2, .type = INTEL_DRAM_DDR5,   .page_mask = 0x3 },
	{ .num_channels = 2, .type = INTEL_DRAM_LPDDR5, .page_mask = 0x3 },
	{}
};

static void tgl_bw_buddy_init(struct intel_display *display)
{
	const struct dram_info *dram_info = intel_dram_info(display);
	const struct buddy_page_mask *table;
	unsigned long abox_mask = DISPLAY_INFO(display)->abox_mask;
	int config, i;

	/* BW_BUDDY registers are not used on dgpu's beyond DG1 */
	if (display->platform.dgfx && !display->platform.dg1)
		return;

	if (intel_display_wa(display, INTEL_DISPLAY_WA_1409767108))
		/* Wa_1409767108 */
		table = wa_1409767108_buddy_page_masks;
	else
		table = tgl_buddy_page_masks;

	for (config = 0; table[config].page_mask != 0; config++)
		if (table[config].num_channels == dram_info->num_channels &&
		    table[config].type == dram_info->type)
			break;

	if (table[config].page_mask == 0) {
		drm_dbg_kms(display->drm,
			    "Unknown memory configuration; disabling address buddy logic.\n");
		for_each_set_bit(i, &abox_mask, BITS_PER_TYPE(abox_mask))
			intel_de_write(display, BW_BUDDY_CTL(i),
				       BW_BUDDY_DISABLE);
	} else {
		for_each_set_bit(i, &abox_mask, BITS_PER_TYPE(abox_mask)) {
			intel_de_write(display, BW_BUDDY_PAGE_MASK(i),
				       table[config].page_mask);

			/* Wa_22010178259:tgl,dg1,rkl,adl-s */
			if (intel_display_wa(display, INTEL_DISPLAY_WA_22010178259))
				intel_de_rmw(display, BW_BUDDY_CTL(i),
					     BW_BUDDY_TLB_REQ_TIMER_MASK,
					     BW_BUDDY_TLB_REQ_TIMER(0x8));
		}
	}
}

static void icl_display_core_init(struct intel_display *display,
				  bool resume)
{
	struct i915_power_domains *power_domains = &display->power.domains;
	struct i915_power_well *well;

	gen9_set_dc_state(display, DC_STATE_DISABLE);

	/* Wa_14011294188:ehl,jsl,tgl,rkl,adl-s */
	if (intel_display_wa(display, INTEL_DISPLAY_WA_14011294188))
		intel_de_rmw(display, SOUTH_DSPCLK_GATE_D, 0,
			     PCH_DPMGUNIT_CLOCK_GATE_DISABLE);

	/* 1. Enable PCH reset handshake. */
	intel_pch_reset_handshake(display, !HAS_PCH_NOP(display));

	if (!HAS_DISPLAY(display))
		return;

Annotation

Implementation Notes