drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
Extension
.c
Size
106703 bytes
Lines
3212
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

sienna_cichlid_is_od_feature_supported(od_settings, SMU_11_0_7_ODCAP_POWER_LIMIT)) {
			od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]);
			od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]);
		} else if ((sienna_cichlid_is_od_feature_supported(od_settings, SMU_11_0_7_ODCAP_POWER_LIMIT))) {
			od_percent_upper = 0;
			od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]);
		}
	}

	dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n",
					od_percent_upper, od_percent_lower, power_limit);

	if (max_power_limit) {
		*max_power_limit = power_limit * (100 + od_percent_upper);
		*max_power_limit /= 100;
	}

	if (min_power_limit) {
		*min_power_limit = power_limit * (100 - od_percent_lower);
		*min_power_limit /= 100;
	}
	return 0;
}

static void sienna_cichlid_get_smartshift_power_percentage(struct smu_context *smu,
					uint32_t *apu_percent,
					uint32_t *dgpu_percent)
{
	struct smu_table_context *smu_table = &smu->smu_table;
	SmuMetrics_V4_t *metrics_v4 =
		&(((SmuMetricsExternal_t *)(smu_table->metrics_table))->SmuMetrics_V4);
	uint16_t powerRatio = 0;
	uint16_t apu_power_limit = 0;
	uint16_t dgpu_power_limit = 0;
	uint32_t apu_boost = 0;
	uint32_t dgpu_boost = 0;
	uint32_t cur_power_limit;

	if (metrics_v4->ApuSTAPMSmartShiftLimit != 0) {
		sienna_cichlid_get_power_limit(smu, &cur_power_limit, NULL, NULL, NULL);
		apu_power_limit = metrics_v4->ApuSTAPMLimit;
		dgpu_power_limit = cur_power_limit;
		powerRatio = (((apu_power_limit +
						  dgpu_power_limit) * 100) /
						  metrics_v4->ApuSTAPMSmartShiftLimit);
		if (powerRatio > 100) {
			apu_power_limit = (apu_power_limit * 100) /
									 powerRatio;
			dgpu_power_limit = (dgpu_power_limit * 100) /
									  powerRatio;
		}
		if (metrics_v4->AverageApuSocketPower > apu_power_limit &&
			 apu_power_limit != 0) {
			apu_boost = ((metrics_v4->AverageApuSocketPower -
							apu_power_limit) * 100) /
							apu_power_limit;
			if (apu_boost > 100)
				apu_boost = 100;
		}

		if (metrics_v4->AverageSocketPower > dgpu_power_limit &&
			 dgpu_power_limit != 0) {
			dgpu_boost = ((metrics_v4->AverageSocketPower -
							 dgpu_power_limit) * 100) /
							 dgpu_power_limit;
			if (dgpu_boost > 100)
				dgpu_boost = 100;
		}

		if (dgpu_boost >= apu_boost)
			apu_boost = 0;
		else
			dgpu_boost = 0;
	}
	*apu_percent = apu_boost;
	*dgpu_percent = dgpu_boost;
}

static int sienna_cichlid_get_smu_metrics_data(struct smu_context *smu,
					       MetricsMember_t member,
					       uint32_t *value)
{
	struct smu_table_context *smu_table= &smu->smu_table;
	SmuMetrics_t *metrics =
		&(((SmuMetricsExternal_t *)(smu_table->metrics_table))->SmuMetrics);
	SmuMetrics_V2_t *metrics_v2 =
		&(((SmuMetricsExternal_t *)(smu_table->metrics_table))->SmuMetrics_V2);
	SmuMetrics_V3_t *metrics_v3 =
		&(((SmuMetricsExternal_t *)(smu_table->metrics_table))->SmuMetrics_V3);
	bool use_metrics_v2 = false;

Annotation

Implementation Notes