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

Commit 5632708f authored by Eric Huang's avatar Eric Huang Committed by Alex Deucher
Browse files

drm/amd/powerplay: add dpm force multiple levels on cz/tonga/fiji/polaris (v2)



Allows you to force multiple levels rather than just one via the new
sysfs interrface.

v2: squash in:
drm/amd/powerplay: ensure clock level set by user is valid.
From Rex.

Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarEric Huang <JinHuiEric.Huang@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 51224389
Loading
Loading
Loading
Loading
+36 −15
Original line number Diff line number Diff line
@@ -362,16 +362,23 @@ static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev,
	struct amdgpu_device *adev = ddev->dev_private;
	int ret;
	long level;
	uint32_t i, mask = 0;
	char sub_str[2];

	ret = kstrtol(buf, 0, &level);
	for (i = 0; i < strlen(buf) - 1; i++) {
		sub_str[0] = *(buf + i);
		sub_str[1] = '\0';
		ret = kstrtol(sub_str, 0, &level);

		if (ret) {
			count = -EINVAL;
			goto fail;
		}
		mask |= 1 << level;
	}

	if (adev->pp_enabled)
		amdgpu_dpm_force_clock_level(adev, PP_SCLK, level);
		amdgpu_dpm_force_clock_level(adev, PP_SCLK, mask);
fail:
	return count;
}
@@ -399,16 +406,23 @@ static ssize_t amdgpu_set_pp_dpm_mclk(struct device *dev,
	struct amdgpu_device *adev = ddev->dev_private;
	int ret;
	long level;
	uint32_t i, mask = 0;
	char sub_str[2];

	ret = kstrtol(buf, 0, &level);
	for (i = 0; i < strlen(buf) - 1; i++) {
		sub_str[0] = *(buf + i);
		sub_str[1] = '\0';
		ret = kstrtol(sub_str, 0, &level);

		if (ret) {
			count = -EINVAL;
			goto fail;
		}
		mask |= 1 << level;
	}

	if (adev->pp_enabled)
		amdgpu_dpm_force_clock_level(adev, PP_MCLK, level);
		amdgpu_dpm_force_clock_level(adev, PP_MCLK, mask);
fail:
	return count;
}
@@ -436,16 +450,23 @@ static ssize_t amdgpu_set_pp_dpm_pcie(struct device *dev,
	struct amdgpu_device *adev = ddev->dev_private;
	int ret;
	long level;
	uint32_t i, mask = 0;
	char sub_str[2];

	ret = kstrtol(buf, 0, &level);
	for (i = 0; i < strlen(buf) - 1; i++) {
		sub_str[0] = *(buf + i);
		sub_str[1] = '\0';
		ret = kstrtol(sub_str, 0, &level);

		if (ret) {
			count = -EINVAL;
			goto fail;
		}
		mask |= 1 << level;
	}

	if (adev->pp_enabled)
		amdgpu_dpm_force_clock_level(adev, PP_PCIE, level);
		amdgpu_dpm_force_clock_level(adev, PP_PCIE, mask);
fail:
	return count;
}
+2 −2
Original line number Diff line number Diff line
@@ -763,7 +763,7 @@ static int pp_dpm_set_pp_table(void *handle, const char *buf, size_t size)
}

static int pp_dpm_force_clock_level(void *handle,
		enum pp_clock_type type, int level)
		enum pp_clock_type type, uint32_t mask)
{
	struct pp_hwmgr *hwmgr;

@@ -779,7 +779,7 @@ static int pp_dpm_force_clock_level(void *handle,
		return 0;
	}

	return hwmgr->hwmgr_func->force_clock_level(hwmgr, type, level);
	return hwmgr->hwmgr_func->force_clock_level(hwmgr, type, mask);
}

static int pp_dpm_print_clock_levels(void *handle,
+3 −3
Original line number Diff line number Diff line
@@ -1729,7 +1729,7 @@ static int cz_get_dal_power_level(struct pp_hwmgr *hwmgr,
}

static int cz_force_clock_level(struct pp_hwmgr *hwmgr,
		enum pp_clock_type type, int level)
		enum pp_clock_type type, uint32_t mask)
{
	if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL)
		return -EINVAL;
@@ -1738,10 +1738,10 @@ static int cz_force_clock_level(struct pp_hwmgr *hwmgr,
	case PP_SCLK:
		smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
				PPSMC_MSG_SetSclkSoftMin,
				(1 << level));
				mask);
		smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
				PPSMC_MSG_SetSclkSoftMax,
				(1 << level));
				mask);
		break;
	default:
		break;
+14 −4
Original line number Diff line number Diff line
@@ -5113,7 +5113,7 @@ static int fiji_set_pp_table(struct pp_hwmgr *hwmgr, const char *buf, size_t siz
}

static int fiji_force_clock_level(struct pp_hwmgr *hwmgr,
		enum pp_clock_type type, int level)
		enum pp_clock_type type, uint32_t mask)
{
	struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);

@@ -5125,20 +5125,30 @@ static int fiji_force_clock_level(struct pp_hwmgr *hwmgr,
		if (!data->sclk_dpm_key_disabled)
			smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
					PPSMC_MSG_SCLKDPM_SetEnabledMask,
					(1 << level));
					data->dpm_level_enable_mask.sclk_dpm_enable_mask & mask);
		break;

	case PP_MCLK:
		if (!data->mclk_dpm_key_disabled)
			smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
					PPSMC_MSG_MCLKDPM_SetEnabledMask,
					(1 << level));
					data->dpm_level_enable_mask.mclk_dpm_enable_mask & mask);
		break;

	case PP_PCIE:
	{
		uint32_t tmp = mask & data->dpm_level_enable_mask.pcie_dpm_enable_mask;
		uint32_t level = 0;

		while (tmp >>= 1)
			level++;

		if (!data->pcie_dpm_key_disabled)
			smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
					PPSMC_MSG_PCIeDPM_ForceLevel,
					(1 << level));
					level);
		break;
	}
	default:
		break;
	}
+12 −4
Original line number Diff line number Diff line
@@ -4767,7 +4767,7 @@ static int polaris10_set_pp_table(struct pp_hwmgr *hwmgr, const char *buf, size_
}

static int polaris10_force_clock_level(struct pp_hwmgr *hwmgr,
		enum pp_clock_type type, int level)
		enum pp_clock_type type, uint32_t mask)
{
	struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend);

@@ -4779,20 +4779,28 @@ static int polaris10_force_clock_level(struct pp_hwmgr *hwmgr,
		if (!data->sclk_dpm_key_disabled)
			smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
					PPSMC_MSG_SCLKDPM_SetEnabledMask,
					(1 << level));
					data->dpm_level_enable_mask.sclk_dpm_enable_mask & mask);
		break;
	case PP_MCLK:
		if (!data->mclk_dpm_key_disabled)
			smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
					PPSMC_MSG_MCLKDPM_SetEnabledMask,
					(1 << level));
					data->dpm_level_enable_mask.mclk_dpm_enable_mask & mask);
		break;
	case PP_PCIE:
	{
		uint32_t tmp = mask & data->dpm_level_enable_mask.pcie_dpm_enable_mask;
		uint32_t level = 0;

		while (tmp >>= 1)
			level++;

		if (!data->pcie_dpm_key_disabled)
			smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
					PPSMC_MSG_PCIeDPM_ForceLevel,
					(1 << level));
					level);
		break;
	}
	default:
		break;
	}
Loading