Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a5278e51 authored by Rex Zhu's avatar Rex Zhu Committed by Alex Deucher
Browse files

drm/amd/pp: Revert gfx/compute profile switch sysfs



The gfx/compute profiling mode switch is only for internally
test. Not a complete solution and unexpectly upstream.
so revert it.

Reviewed-by: default avatarEvan Quan <evan.quan@amd.com>
Acked-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarRex Zhu <Rex.Zhu@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 180a8beb
Loading
Loading
Loading
Loading
+0 −8
Original line number Diff line number Diff line
@@ -341,14 +341,6 @@ enum amdgpu_pcie_gen {
		((adev)->powerplay.pp_funcs->reset_power_profile_state(\
			(adev)->powerplay.pp_handle, request))

#define amdgpu_dpm_get_power_profile_state(adev, query) \
		((adev)->powerplay.pp_funcs->get_power_profile_state(\
			(adev)->powerplay.pp_handle, query))

#define amdgpu_dpm_set_power_profile_state(adev, request) \
		((adev)->powerplay.pp_funcs->set_power_profile_state(\
			(adev)->powerplay.pp_handle, request))

#define amdgpu_dpm_switch_power_profile(adev, type) \
		((adev)->powerplay.pp_funcs->switch_power_profile(\
			(adev)->powerplay.pp_handle, type))
+0 −180
Original line number Diff line number Diff line
@@ -734,161 +734,6 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev,
	return -EINVAL;
}

static ssize_t amdgpu_get_pp_power_profile(struct device *dev,
		char *buf, struct amd_pp_profile *query)
{
	struct drm_device *ddev = dev_get_drvdata(dev);
	struct amdgpu_device *adev = ddev->dev_private;
	int ret = 0xff;

	if (adev->powerplay.pp_funcs->get_power_profile_state)
		ret = amdgpu_dpm_get_power_profile_state(
				adev, query);

	if (ret)
		return ret;

	return snprintf(buf, PAGE_SIZE,
			"%d %d %d %d %d\n",
			query->min_sclk / 100,
			query->min_mclk / 100,
			query->activity_threshold,
			query->up_hyst,
			query->down_hyst);
}

static ssize_t amdgpu_get_pp_gfx_power_profile(struct device *dev,
		struct device_attribute *attr,
		char *buf)
{
	struct amd_pp_profile query = {0};

	query.type = AMD_PP_GFX_PROFILE;

	return amdgpu_get_pp_power_profile(dev, buf, &query);
}

static ssize_t amdgpu_get_pp_compute_power_profile(struct device *dev,
		struct device_attribute *attr,
		char *buf)
{
	struct amd_pp_profile query = {0};

	query.type = AMD_PP_COMPUTE_PROFILE;

	return amdgpu_get_pp_power_profile(dev, buf, &query);
}

static ssize_t amdgpu_set_pp_power_profile(struct device *dev,
		const char *buf,
		size_t count,
		struct amd_pp_profile *request)
{
	struct drm_device *ddev = dev_get_drvdata(dev);
	struct amdgpu_device *adev = ddev->dev_private;
	uint32_t loop = 0;
	char *sub_str, buf_cpy[128], *tmp_str;
	const char delimiter[3] = {' ', '\n', '\0'};
	long int value;
	int ret = 0xff;

	if (strncmp("reset", buf, strlen("reset")) == 0) {
		if (adev->powerplay.pp_funcs->reset_power_profile_state)
			ret = amdgpu_dpm_reset_power_profile_state(
					adev, request);
		if (ret) {
			count = -EINVAL;
			goto fail;
		}
		return count;
	}

	if (strncmp("set", buf, strlen("set")) == 0) {
		if (adev->powerplay.pp_funcs->set_power_profile_state)
			ret = amdgpu_dpm_set_power_profile_state(
					adev, request);

		if (ret) {
			count = -EINVAL;
			goto fail;
		}
		return count;
	}

	if (count + 1 >= 128) {
		count = -EINVAL;
		goto fail;
	}

	memcpy(buf_cpy, buf, count + 1);
	tmp_str = buf_cpy;

	while (tmp_str[0]) {
		sub_str = strsep(&tmp_str, delimiter);
		ret = kstrtol(sub_str, 0, &value);
		if (ret) {
			count = -EINVAL;
			goto fail;
		}

		switch (loop) {
		case 0:
			/* input unit MHz convert to dpm table unit 10KHz*/
			request->min_sclk = (uint32_t)value * 100;
			break;
		case 1:
			/* input unit MHz convert to dpm table unit 10KHz*/
			request->min_mclk = (uint32_t)value * 100;
			break;
		case 2:
			request->activity_threshold = (uint16_t)value;
			break;
		case 3:
			request->up_hyst = (uint8_t)value;
			break;
		case 4:
			request->down_hyst = (uint8_t)value;
			break;
		default:
			break;
		}

		loop++;
	}
	if (adev->powerplay.pp_funcs->set_power_profile_state)
		ret = amdgpu_dpm_set_power_profile_state(adev, request);

	if (ret)
		count = -EINVAL;

fail:
	return count;
}

static ssize_t amdgpu_set_pp_gfx_power_profile(struct device *dev,
		struct device_attribute *attr,
		const char *buf,
		size_t count)
{
	struct amd_pp_profile request = {0};

	request.type = AMD_PP_GFX_PROFILE;

	return amdgpu_set_pp_power_profile(dev, buf, count, &request);
}

static ssize_t amdgpu_set_pp_compute_power_profile(struct device *dev,
		struct device_attribute *attr,
		const char *buf,
		size_t count)
{
	struct amd_pp_profile request = {0};

	request.type = AMD_PP_COMPUTE_PROFILE;

	return amdgpu_set_pp_power_profile(dev, buf, count, &request);
}

static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, amdgpu_get_dpm_state, amdgpu_set_dpm_state);
static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR,
		   amdgpu_get_dpm_forced_performance_level,
@@ -916,12 +761,6 @@ static DEVICE_ATTR(pp_sclk_od, S_IRUGO | S_IWUSR,
static DEVICE_ATTR(pp_mclk_od, S_IRUGO | S_IWUSR,
		amdgpu_get_pp_mclk_od,
		amdgpu_set_pp_mclk_od);
static DEVICE_ATTR(pp_gfx_power_profile, S_IRUGO | S_IWUSR,
		amdgpu_get_pp_gfx_power_profile,
		amdgpu_set_pp_gfx_power_profile);
static DEVICE_ATTR(pp_compute_power_profile, S_IRUGO | S_IWUSR,
		amdgpu_get_pp_compute_power_profile,
		amdgpu_set_pp_compute_power_profile);
static DEVICE_ATTR(pp_power_profile_mode, S_IRUGO | S_IWUSR,
		amdgpu_get_pp_power_profile_mode,
		amdgpu_set_pp_power_profile_mode);
@@ -1766,21 +1605,6 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
		DRM_ERROR("failed to create device file pp_mclk_od\n");
		return ret;
	}
	ret = device_create_file(adev->dev,
			&dev_attr_pp_gfx_power_profile);
	if (ret) {
		DRM_ERROR("failed to create device file	"
				"pp_gfx_power_profile\n");
		return ret;
	}
	ret = device_create_file(adev->dev,
			&dev_attr_pp_compute_power_profile);
	if (ret) {
		DRM_ERROR("failed to create device file	"
				"pp_compute_power_profile\n");
		return ret;
	}

	ret = device_create_file(adev->dev,
			&dev_attr_pp_power_profile_mode);
	if (ret) {
@@ -1826,10 +1650,6 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev)
	device_remove_file(adev->dev, &dev_attr_pp_dpm_pcie);
	device_remove_file(adev->dev, &dev_attr_pp_sclk_od);
	device_remove_file(adev->dev, &dev_attr_pp_mclk_od);
	device_remove_file(adev->dev,
			&dev_attr_pp_gfx_power_profile);
	device_remove_file(adev->dev,
			&dev_attr_pp_compute_power_profile);
	device_remove_file(adev->dev,
			&dev_attr_pp_power_profile_mode);
	device_remove_file(adev->dev,
+0 −256
Original line number Diff line number Diff line
@@ -3695,40 +3695,6 @@ static int ci_find_boot_level(struct ci_single_dpm_table *table,
	return ret;
}

static void ci_save_default_power_profile(struct amdgpu_device *adev)
{
	struct ci_power_info *pi = ci_get_pi(adev);
	struct SMU7_Discrete_GraphicsLevel *levels =
				pi->smc_state_table.GraphicsLevel;
	uint32_t min_level = 0;

	pi->default_gfx_power_profile.activity_threshold =
			be16_to_cpu(levels[0].ActivityLevel);
	pi->default_gfx_power_profile.up_hyst = levels[0].UpH;
	pi->default_gfx_power_profile.down_hyst = levels[0].DownH;
	pi->default_gfx_power_profile.type = AMD_PP_GFX_PROFILE;

	pi->default_compute_power_profile = pi->default_gfx_power_profile;
	pi->default_compute_power_profile.type = AMD_PP_COMPUTE_PROFILE;

	/* Optimize compute power profile: Use only highest
	 * 2 power levels (if more than 2 are available), Hysteresis:
	 * 0ms up, 5ms down
	 */
	if (pi->smc_state_table.GraphicsDpmLevelCount > 2)
		min_level = pi->smc_state_table.GraphicsDpmLevelCount - 2;
	else if (pi->smc_state_table.GraphicsDpmLevelCount == 2)
		min_level = 1;
	pi->default_compute_power_profile.min_sclk =
			be32_to_cpu(levels[min_level].SclkFrequency);

	pi->default_compute_power_profile.up_hyst = 0;
	pi->default_compute_power_profile.down_hyst = 5;

	pi->gfx_power_profile = pi->default_gfx_power_profile;
	pi->compute_power_profile = pi->default_compute_power_profile;
}

static int ci_init_smc_table(struct amdgpu_device *adev)
{
	struct ci_power_info *pi = ci_get_pi(adev);
@@ -3874,8 +3840,6 @@ static int ci_init_smc_table(struct amdgpu_device *adev)
	if (ret)
		return ret;

	ci_save_default_power_profile(adev);

	return 0;
}

@@ -6753,222 +6717,6 @@ static int ci_dpm_set_mclk_od(void *handle, uint32_t value)
	return 0;
}

static int ci_dpm_get_power_profile_state(void *handle,
		struct amd_pp_profile *query)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
	struct ci_power_info *pi = ci_get_pi(adev);

	if (!pi || !query)
		return -EINVAL;

	if (query->type == AMD_PP_GFX_PROFILE)
		memcpy(query, &pi->gfx_power_profile,
				sizeof(struct amd_pp_profile));
	else if (query->type == AMD_PP_COMPUTE_PROFILE)
		memcpy(query, &pi->compute_power_profile,
				sizeof(struct amd_pp_profile));
	else
		return -EINVAL;

	return 0;
}

static int ci_populate_requested_graphic_levels(struct amdgpu_device *adev,
		struct amd_pp_profile *request)
{
	struct ci_power_info *pi = ci_get_pi(adev);
	struct ci_dpm_table *dpm_table = &(pi->dpm_table);
	struct SMU7_Discrete_GraphicsLevel *levels =
			pi->smc_state_table.GraphicsLevel;
	uint32_t array = pi->dpm_table_start +
			offsetof(SMU7_Discrete_DpmTable, GraphicsLevel);
	uint32_t array_size = sizeof(struct SMU7_Discrete_GraphicsLevel) *
			SMU7_MAX_LEVELS_GRAPHICS;
	uint32_t i;

	for (i = 0; i < dpm_table->sclk_table.count; i++) {
		levels[i].ActivityLevel =
				cpu_to_be16(request->activity_threshold);
		levels[i].EnabledForActivity = 1;
		levels[i].UpH = request->up_hyst;
		levels[i].DownH = request->down_hyst;
	}

	return amdgpu_ci_copy_bytes_to_smc(adev, array, (uint8_t *)levels,
				array_size, pi->sram_end);
}

static void ci_find_min_clock_masks(struct amdgpu_device *adev,
		uint32_t *sclk_mask, uint32_t *mclk_mask,
		uint32_t min_sclk, uint32_t min_mclk)
{
	struct ci_power_info *pi = ci_get_pi(adev);
	struct ci_dpm_table *dpm_table = &(pi->dpm_table);
	uint32_t i;

	for (i = 0; i < dpm_table->sclk_table.count; i++) {
		if (dpm_table->sclk_table.dpm_levels[i].enabled &&
			dpm_table->sclk_table.dpm_levels[i].value >= min_sclk)
			*sclk_mask |= 1 << i;
	}

	for (i = 0; i < dpm_table->mclk_table.count; i++) {
		if (dpm_table->mclk_table.dpm_levels[i].enabled &&
			dpm_table->mclk_table.dpm_levels[i].value >= min_mclk)
			*mclk_mask |= 1 << i;
	}
}

static int ci_set_power_profile_state(struct amdgpu_device *adev,
		struct amd_pp_profile *request)
{
	struct ci_power_info *pi = ci_get_pi(adev);
	int tmp_result, result = 0;
	uint32_t sclk_mask = 0, mclk_mask = 0;

	tmp_result = ci_freeze_sclk_mclk_dpm(adev);
	if (tmp_result) {
		DRM_ERROR("Failed to freeze SCLK MCLK DPM!");
		result = tmp_result;
	}

	tmp_result = ci_populate_requested_graphic_levels(adev,
			request);
	if (tmp_result) {
		DRM_ERROR("Failed to populate requested graphic levels!");
		result = tmp_result;
	}

	tmp_result = ci_unfreeze_sclk_mclk_dpm(adev);
	if (tmp_result) {
		DRM_ERROR("Failed to unfreeze SCLK MCLK DPM!");
		result = tmp_result;
	}

	ci_find_min_clock_masks(adev, &sclk_mask, &mclk_mask,
			request->min_sclk, request->min_mclk);

	if (sclk_mask) {
		if (!pi->sclk_dpm_key_disabled)
			amdgpu_ci_send_msg_to_smc_with_parameter(
				adev,
				PPSMC_MSG_SCLKDPM_SetEnabledMask,
				pi->dpm_level_enable_mask.
				sclk_dpm_enable_mask &
				sclk_mask);
	}

	if (mclk_mask) {
		if (!pi->mclk_dpm_key_disabled)
			amdgpu_ci_send_msg_to_smc_with_parameter(
				adev,
				PPSMC_MSG_MCLKDPM_SetEnabledMask,
				pi->dpm_level_enable_mask.
				mclk_dpm_enable_mask &
				mclk_mask);
	}


	return result;
}

static int ci_dpm_set_power_profile_state(void *handle,
		struct amd_pp_profile *request)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
	struct ci_power_info *pi = ci_get_pi(adev);
	int ret = -1;

	if (!pi || !request)
		return -EINVAL;

	if (adev->pm.dpm.forced_level !=
			AMD_DPM_FORCED_LEVEL_AUTO)
		return -EINVAL;

	if (request->min_sclk ||
		request->min_mclk ||
		request->activity_threshold ||
		request->up_hyst ||
		request->down_hyst) {
		if (request->type == AMD_PP_GFX_PROFILE)
			memcpy(&pi->gfx_power_profile, request,
					sizeof(struct amd_pp_profile));
		else if (request->type == AMD_PP_COMPUTE_PROFILE)
			memcpy(&pi->compute_power_profile, request,
					sizeof(struct amd_pp_profile));
		else
			return -EINVAL;

		if (request->type == pi->current_power_profile)
			ret = ci_set_power_profile_state(
					adev,
					request);
	} else {
		/* set power profile if it exists */
		switch (request->type) {
		case AMD_PP_GFX_PROFILE:
			ret = ci_set_power_profile_state(
				adev,
				&pi->gfx_power_profile);
			break;
		case AMD_PP_COMPUTE_PROFILE:
			ret = ci_set_power_profile_state(
				adev,
				&pi->compute_power_profile);
			break;
		default:
			return -EINVAL;
		}
	}

	if (!ret)
		pi->current_power_profile = request->type;

	return 0;
}

static int ci_dpm_reset_power_profile_state(void *handle,
		struct amd_pp_profile *request)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
	struct ci_power_info *pi = ci_get_pi(adev);

	if (!pi || !request)
		return -EINVAL;

	if (request->type == AMD_PP_GFX_PROFILE) {
		pi->gfx_power_profile = pi->default_gfx_power_profile;
		return ci_dpm_set_power_profile_state(adev,
					  &pi->gfx_power_profile);
	} else if (request->type == AMD_PP_COMPUTE_PROFILE) {
		pi->compute_power_profile =
			pi->default_compute_power_profile;
		return ci_dpm_set_power_profile_state(adev,
					  &pi->compute_power_profile);
	} else
		return -EINVAL;
}

static int ci_dpm_switch_power_profile(void *handle,
		enum amd_pp_profile_type type)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
	struct ci_power_info *pi = ci_get_pi(adev);
	struct amd_pp_profile request = {0};

	if (!pi)
		return -EINVAL;

	if (pi->current_power_profile != type) {
		request.type = type;
		return ci_dpm_set_power_profile_state(adev, &request);
	}

	return 0;
}

static int ci_dpm_read_sensor(void *handle, int idx,
			      void *value, int *size)
{
@@ -7053,10 +6801,6 @@ const struct amd_pm_funcs ci_dpm_funcs = {
	.set_mclk_od = ci_dpm_set_mclk_od,
	.check_state_equal = ci_check_state_equal,
	.get_vce_clock_state = amdgpu_get_vce_clock_state,
	.get_power_profile_state = ci_dpm_get_power_profile_state,
	.set_power_profile_state = ci_dpm_set_power_profile_state,
	.reset_power_profile_state = ci_dpm_reset_power_profile_state,
	.switch_power_profile = ci_dpm_switch_power_profile,
	.read_sensor = ci_dpm_read_sensor,
};

+0 −7
Original line number Diff line number Diff line
@@ -295,13 +295,6 @@ struct ci_power_info {
	bool fan_is_controlled_by_smc;
	u32 t_min;
	u32 fan_ctrl_default_mode;

	/* power profile */
	struct amd_pp_profile gfx_power_profile;
	struct amd_pp_profile compute_power_profile;
	struct amd_pp_profile default_gfx_power_profile;
	struct amd_pp_profile default_compute_power_profile;
	enum amd_pp_profile_type current_power_profile;
};

#define CISLANDS_VOLTAGE_CONTROL_NONE                   0x0
+0 −7
Original line number Diff line number Diff line
@@ -252,13 +252,6 @@ struct amd_pm_funcs {
	int (*get_pp_table)(void *handle, char **table);
	int (*set_pp_table)(void *handle, const char *buf, size_t size);
	void (*debugfs_print_current_performance_level)(void *handle, struct seq_file *m);

	int (*reset_power_profile_state)(void *handle,
			struct amd_pp_profile *request);
	int (*get_power_profile_state)(void *handle,
			struct amd_pp_profile *query);
	int (*set_power_profile_state)(void *handle,
			struct amd_pp_profile *request);
	int (*switch_power_profile)(void *handle,
			enum amd_pp_profile_type type);
/* export to amdgpu */
Loading