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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/gt/selftest_rps.c
Extension
.c
Size
32305 bytes
Lines
1352
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 (srm) {
			*cs++ = MI_STORE_REGISTER_MEM_GEN8;
			*cs++ = i915_mmio_reg_offset(CS_GPR(COUNT));
			*cs++ = lower_32_bits(i915_vma_offset(vma) + end * sizeof(*cs));
			*cs++ = upper_32_bits(i915_vma_offset(vma) + end * sizeof(*cs));
		}
	}

	*cs++ = MI_BATCH_BUFFER_START_GEN8;
	*cs++ = lower_32_bits(i915_vma_offset(vma) + loop * sizeof(*cs));
	*cs++ = upper_32_bits(i915_vma_offset(vma) + loop * sizeof(*cs));
	GEM_BUG_ON(cs - base > end);

	i915_gem_object_flush_map(obj);

	*cancel = base + loop;
	*counter = srm ? memset32(base + end, 0, 1) : NULL;
	return vma;

err_unpin:
	i915_vma_unpin(vma);
err_unlock:
	i915_vma_unlock(vma);
err_put:
	i915_gem_object_put(obj);
	return ERR_PTR(err);
}

static u8 wait_for_freq(struct intel_rps *rps, u8 freq, int timeout_ms)
{
	u8 history[64], i;
	unsigned long end;
	int sleep;

	i = 0;
	memset(history, freq, sizeof(history));
	sleep = 20;

	/* The PCU does not change instantly, but drifts towards the goal? */
	end = jiffies + msecs_to_jiffies(timeout_ms);
	do {
		u8 act;

		act = read_cagf(rps);
		if (time_after(jiffies, end))
			return act;

		/* Target acquired */
		if (act == freq)
			return act;

		/* Any change within the last N samples? */
		if (!memchr_inv(history, act, sizeof(history)))
			return act;

		history[i] = act;
		i = (i + 1) % ARRAY_SIZE(history);

		usleep_range(sleep, 2 * sleep);
		sleep *= 2;
		if (sleep > timeout_ms * 20)
			sleep = timeout_ms * 20;
	} while (1);
}

static u8 rps_set_check(struct intel_rps *rps, u8 freq)
{
	mutex_lock(&rps->lock);
	GEM_BUG_ON(!intel_rps_is_active(rps));
	if (wait_for(!intel_rps_set(rps, freq), 50)) {
		mutex_unlock(&rps->lock);
		return 0;
	}
	GEM_BUG_ON(rps->last_freq != freq);
	mutex_unlock(&rps->lock);

	return wait_for_freq(rps, freq, 50);
}

static void show_pstate_limits(struct intel_rps *rps)
{
	struct drm_i915_private *i915 = rps_to_i915(rps);

	if (IS_BROXTON(i915)) {
		pr_info("P_STATE_CAP[%x]: 0x%08x\n",
			i915_mmio_reg_offset(BXT_RP_STATE_CAP),
			intel_uncore_read(rps_to_uncore(rps),
					  BXT_RP_STATE_CAP));
	} else if (GRAPHICS_VER(i915) == 9) {
		pr_info("P_STATE_LIMITS[%x]: 0x%08x\n",

Annotation

Implementation Notes