drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
Extension
.c
Size
23316 bytes
Lines
907
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 (wait_for(slpc_is_running(slpc), SLPC_RESET_TIMEOUT_MS)) {
			guc_probe_error(guc, "SLPC not enabled! State = %s\n",
					slpc_get_state_string(slpc));
			return -EIO;
		}
	}

	return 0;
}

static u32 slpc_decode_min_freq(struct intel_guc_slpc *slpc)
{
	struct slpc_shared_data *data = slpc->vaddr;

	GEM_BUG_ON(!slpc->vma);

	return	DIV_ROUND_CLOSEST(REG_FIELD_GET(SLPC_MIN_UNSLICE_FREQ_MASK,
				  data->task_state_data.freq) *
				  GT_FREQUENCY_MULTIPLIER, GEN9_FREQ_SCALER);
}

static u32 slpc_decode_max_freq(struct intel_guc_slpc *slpc)
{
	struct slpc_shared_data *data = slpc->vaddr;

	GEM_BUG_ON(!slpc->vma);

	return	DIV_ROUND_CLOSEST(REG_FIELD_GET(SLPC_MAX_UNSLICE_FREQ_MASK,
				  data->task_state_data.freq) *
				  GT_FREQUENCY_MULTIPLIER, GEN9_FREQ_SCALER);
}

static void slpc_shared_data_reset(struct intel_guc_slpc *slpc)
{
	struct drm_i915_private *i915 = slpc_to_i915(slpc);
	struct slpc_shared_data *data = slpc->vaddr;

	memset(data, 0, sizeof(struct slpc_shared_data));
	data->header.size = sizeof(struct slpc_shared_data);

	/* Enable only GTPERF task, disable others */
	slpc_mem_set_enabled(data, SLPC_PARAM_TASK_ENABLE_GTPERF,
			     SLPC_PARAM_TASK_DISABLE_GTPERF);

	/*
	 * Don't allow balancer related algorithms on platforms before
	 * Xe_LPG, where GuC started to restrict it to TDP limited scenarios.
	 */
	if (GRAPHICS_VER_FULL(i915) < IP_VER(12, 70)) {
		slpc_mem_set_disabled(data, SLPC_PARAM_TASK_ENABLE_BALANCER,
				      SLPC_PARAM_TASK_DISABLE_BALANCER);

		slpc_mem_set_disabled(data, SLPC_PARAM_TASK_ENABLE_DCC,
				      SLPC_PARAM_TASK_DISABLE_DCC);
	}
}

/**
 * intel_guc_slpc_set_max_freq() - Set max frequency limit for SLPC.
 * @slpc: pointer to intel_guc_slpc.
 * @val: frequency (MHz)
 *
 * This function will invoke GuC SLPC action to update the max frequency
 * limit for unslice.
 *
 * Return: 0 on success, non-zero error code on failure.
 */
int intel_guc_slpc_set_max_freq(struct intel_guc_slpc *slpc, u32 val)
{
	struct drm_i915_private *i915 = slpc_to_i915(slpc);
	intel_wakeref_t wakeref;
	int ret;

	if (val < slpc->min_freq ||
	    val > slpc->rp0_freq ||
	    val < slpc->min_freq_softlimit)
		return -EINVAL;

	with_intel_runtime_pm(&i915->runtime_pm, wakeref) {
		ret = slpc_set_param(slpc,
				     SLPC_PARAM_GLOBAL_MAX_GT_UNSLICE_FREQ_MHZ,
				     val);

		/* Return standardized err code for sysfs calls */
		if (ret)
			ret = -EIO;
	}

	if (!ret)
		slpc->max_freq_softlimit = val;

Annotation

Implementation Notes