Commit 488f211d authored by Evan Quan's avatar Evan Quan Committed by Alex Deucher
Browse files

drm/amd/pm: correct the power limits reporting on OOB supported



As OOB(out-of-band) interface may be used to update the power limits.
Thus to make sure the power limits reporting of our driver always
reflects the correct values, the internal cache must be aligned
carefully.

V2: add support for out-of-band of other ASICs
    align cached current power limit with OOB imposed

Signed-off-by: default avatarEvan Quan <evan.quan@amd.com>
Reviewed-By: default avatarHarish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent c89d2a2f
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -765,7 +765,10 @@ struct pptable_funcs {
	/**
	 * @get_power_limit: Get the device's power limits.
	 */
	int (*get_power_limit)(struct smu_context *smu);
	int (*get_power_limit)(struct smu_context *smu,
			       uint32_t *current_power_limit,
			       uint32_t *default_power_limit,
			       uint32_t *max_power_limit);

	/**
	 * @get_ppt_limit: Get the device's ppt limits.
+13 −1
Original line number Diff line number Diff line
@@ -688,7 +688,10 @@ static int smu_late_init(void *handle)
		return ret;
	}

	ret = smu_get_asic_power_limits(smu);
	ret = smu_get_asic_power_limits(smu,
					&smu->current_power_limit,
					&smu->default_power_limit,
					&smu->max_power_limit);
	if (ret) {
		dev_err(adev->dev, "Failed to get asic power limits!\n");
		return ret;
@@ -2238,6 +2241,15 @@ int smu_get_power_limit(void *handle,
	} else {
		switch (limit_level) {
		case SMU_PPT_LIMIT_CURRENT:
			if ((smu->adev->asic_type == CHIP_ALDEBARAN) ||
			     (smu->adev->asic_type == CHIP_SIENNA_CICHLID) ||
			     (smu->adev->asic_type == CHIP_NAVY_FLOUNDER) ||
			     (smu->adev->asic_type == CHIP_DIMGREY_CAVEFISH) ||
			     (smu->adev->asic_type == CHIP_BEIGE_GOBY))
				ret = smu_get_asic_power_limits(smu,
								&smu->current_power_limit,
								NULL,
								NULL);
			*limit = smu->current_power_limit;
			break;
		case SMU_PPT_LIMIT_DEFAULT:
+18 −8
Original line number Diff line number Diff line
@@ -1194,7 +1194,10 @@ static int arcturus_get_fan_parameters(struct smu_context *smu)
	return 0;
}

static int arcturus_get_power_limit(struct smu_context *smu)
static int arcturus_get_power_limit(struct smu_context *smu,
				    uint32_t *current_power_limit,
				    uint32_t *default_power_limit,
				    uint32_t *max_power_limit)
{
	struct smu_11_0_powerplay_table *powerplay_table =
		(struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table;
@@ -1210,8 +1213,13 @@ static int arcturus_get_power_limit(struct smu_context *smu)
		power_limit =
			pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
	}
	smu->current_power_limit = smu->default_power_limit = power_limit;

	if (current_power_limit)
		*current_power_limit = power_limit;
	if (default_power_limit)
		*default_power_limit = power_limit;

	if (max_power_limit) {
		if (smu->od_enabled) {
			od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);

@@ -1220,7 +1228,9 @@ static int arcturus_get_power_limit(struct smu_context *smu)
			power_limit *= (100 + od_percent);
			power_limit /= 100;
		}
	smu->max_power_limit = power_limit;

		*max_power_limit = power_limit;
	}

	return 0;
}
+19 −9
Original line number Diff line number Diff line
@@ -2136,7 +2136,10 @@ static int navi10_display_disable_memory_clock_switch(struct smu_context *smu,
	return ret;
}

static int navi10_get_power_limit(struct smu_context *smu)
static int navi10_get_power_limit(struct smu_context *smu,
				  uint32_t *current_power_limit,
				  uint32_t *default_power_limit,
				  uint32_t *max_power_limit)
{
	struct smu_11_0_powerplay_table *powerplay_table =
		(struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table;
@@ -2153,8 +2156,13 @@ static int navi10_get_power_limit(struct smu_context *smu)
		power_limit =
			pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
	}
	smu->current_power_limit = smu->default_power_limit = power_limit;

	if (current_power_limit)
		*current_power_limit = power_limit;
	if (default_power_limit)
		*default_power_limit = power_limit;

	if (max_power_limit) {
		if (smu->od_enabled &&
		    navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_POWER_LIMIT)) {
			od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
@@ -2164,7 +2172,9 @@ static int navi10_get_power_limit(struct smu_context *smu)
			power_limit *= (100 + od_percent);
			power_limit /= 100;
		}
	smu->max_power_limit = power_limit;

		*max_power_limit = power_limit;
	}

	return 0;
}
+17 −8
Original line number Diff line number Diff line
@@ -1791,7 +1791,10 @@ static int sienna_cichlid_display_disable_memory_clock_switch(struct smu_context
	return ret;
}

static int sienna_cichlid_get_power_limit(struct smu_context *smu)
static int sienna_cichlid_get_power_limit(struct smu_context *smu,
					  uint32_t *current_power_limit,
					  uint32_t *default_power_limit,
					  uint32_t *max_power_limit)
{
	struct smu_11_0_7_powerplay_table *powerplay_table =
		(struct smu_11_0_7_powerplay_table *)smu->smu_table.power_play_table;
@@ -1804,8 +1807,13 @@ static int sienna_cichlid_get_power_limit(struct smu_context *smu)
		power_limit =
			table_member[PPT_THROTTLER_PPT0];
	}
	smu->current_power_limit = smu->default_power_limit = power_limit;

	if (current_power_limit)
		*current_power_limit = power_limit;
	if (default_power_limit)
		*default_power_limit = power_limit;

	if (max_power_limit) {
		if (smu->od_enabled) {
			od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]);

@@ -1814,7 +1822,8 @@ static int sienna_cichlid_get_power_limit(struct smu_context *smu)
			power_limit *= (100 + od_percent);
			power_limit /= 100;
		}
	smu->max_power_limit = power_limit;
		*max_power_limit = power_limit;
	}

	return 0;
}
Loading