drivers/gpu/drm/i915/gt/intel_sseu_debugfs.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/i915/gt/intel_sseu_debugfs.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/gt/intel_sseu_debugfs.c
Extension
.c
Size
8410 bytes
Lines
302
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

if (IS_GEN9_LP(gt->i915)) {
				if (!(s_reg[s] & (GEN9_PGCTL_SS_ACK(ss))))
					/* skip disabled subslice */
					continue;

				sseu->subslice_mask.hsw[s] |= BIT(ss);
			}

			eu_cnt = eu_reg[2 * s + ss / 2] & eu_mask[ss % 2];
			eu_cnt = 2 * hweight32(eu_cnt);

			sseu->eu_total += eu_cnt;
			sseu->eu_per_subslice = max_t(unsigned int,
						      sseu->eu_per_subslice,
						      eu_cnt);
		}
	}
#undef SS_MAX
}

static void bdw_sseu_device_status(struct intel_gt *gt,
				   struct sseu_dev_info *sseu)
{
	const struct intel_gt_info *info = &gt->info;
	u32 slice_info = intel_uncore_read(gt->uncore, GEN8_GT_SLICE_INFO);
	int s;

	sseu->slice_mask = slice_info & GEN8_LSLICESTAT_MASK;

	if (sseu->slice_mask) {
		sseu->eu_per_subslice = info->sseu.eu_per_subslice;
		for (s = 0; s < fls(sseu->slice_mask); s++)
			sseu->subslice_mask.hsw[s] = info->sseu.subslice_mask.hsw[s];
		sseu->eu_total = sseu->eu_per_subslice *
				 intel_sseu_subslice_total(sseu);

		/* subtract fused off EU(s) from enabled slice(s) */
		for (s = 0; s < fls(sseu->slice_mask); s++) {
			u8 subslice_7eu = info->sseu.subslice_7eu[s];

			sseu->eu_total -= hweight8(subslice_7eu);
		}
	}
}

static void i915_print_sseu_info(struct seq_file *m,
				 bool is_available_info,
				 bool has_pooled_eu,
				 const struct sseu_dev_info *sseu)
{
	const char *type = is_available_info ? "Available" : "Enabled";

	seq_printf(m, "  %s Slice Mask: %04x\n", type,
		   sseu->slice_mask);
	seq_printf(m, "  %s Slice Total: %u\n", type,
		   hweight8(sseu->slice_mask));
	seq_printf(m, "  %s Subslice Total: %u\n", type,
		   intel_sseu_subslice_total(sseu));
	intel_sseu_print_ss_info(type, sseu, m);
	seq_printf(m, "  %s EU Total: %u\n", type,
		   sseu->eu_total);
	seq_printf(m, "  %s EU Per Subslice: %u\n", type,
		   sseu->eu_per_subslice);

	if (!is_available_info)
		return;

	seq_printf(m, "  Has Pooled EU: %s\n", str_yes_no(has_pooled_eu));
	if (has_pooled_eu)
		seq_printf(m, "  Min EU in pool: %u\n", sseu->min_eu_in_pool);

	seq_printf(m, "  Has Slice Power Gating: %s\n",
		   str_yes_no(sseu->has_slice_pg));
	seq_printf(m, "  Has Subslice Power Gating: %s\n",
		   str_yes_no(sseu->has_subslice_pg));
	seq_printf(m, "  Has EU Power Gating: %s\n",
		   str_yes_no(sseu->has_eu_pg));
}

/*
 * this is called from top-level debugfs as well, so we can't get the gt from
 * the seq_file.
 */
int intel_sseu_status(struct seq_file *m, struct intel_gt *gt)
{
	struct drm_i915_private *i915 = gt->i915;
	const struct intel_gt_info *info = &gt->info;
	struct sseu_dev_info *sseu;
	intel_wakeref_t wakeref;

Annotation

Implementation Notes