Commit bd8dcea9 authored by Xiaomeng Hou's avatar Xiaomeng Hou Committed by Alex Deucher
Browse files

drm/amd/pm: add callbacks to read/write sysfs file pp_power_profile_mode



Implement the sysfs API for getting/setting pp_power_profile_mode for
yellow carp.

Signed-off-by: default avatarXiaomeng Hou <Xiaomeng.Hou@amd.com>
Reviewed-by: default avatarHuang Rui <ray.huang@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 40954754
Loading
Loading
Loading
Loading
+86 −0
Original line number Diff line number Diff line
@@ -136,6 +136,14 @@ static struct cmn2asic_mapping yellow_carp_table_map[SMU_TABLE_COUNT] = {
	TAB_MAP_VALID(DPMCLOCKS),
};

static struct cmn2asic_mapping yellow_carp_workload_map[PP_SMC_POWER_PROFILE_COUNT] = {
	WORKLOAD_MAP(PP_SMC_POWER_PROFILE_FULLSCREEN3D,		WORKLOAD_PPLIB_FULL_SCREEN_3D_BIT),
	WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VIDEO,		WORKLOAD_PPLIB_VIDEO_BIT),
	WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VR,			WORKLOAD_PPLIB_VR_BIT),
	WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE,		WORKLOAD_PPLIB_COMPUTE_BIT),
	WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM,		WORKLOAD_PPLIB_CUSTOM_BIT),
};
	
static int yellow_carp_init_smc_tables(struct smu_context *smu)
{
	struct smu_table_context *smu_table = &smu->smu_table;
@@ -463,6 +471,81 @@ static int yellow_carp_set_watermarks_table(struct smu_context *smu,
	return 0;
}

static int yellow_carp_get_power_profile_mode(struct smu_context *smu,
						char *buf)
{
	static const char *profile_name[] = {
					"BOOTUP_DEFAULT",
					"3D_FULL_SCREEN",
					"POWER_SAVING",
					"VIDEO",
					"VR",
					"COMPUTE",
					"CUSTOM"};
	uint32_t i, size = 0;
	int16_t workload_type = 0;

	if (!buf)
		return -EINVAL;

	for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) {
		/*
		 * Conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT.
		 * Not all profile modes are supported on yellow carp.
		 */
		workload_type = smu_cmn_to_asic_specific_index(smu,
							       CMN2ASIC_MAPPING_WORKLOAD,
							       i);

		if (workload_type < 0)
			continue;

		size += sprintf(buf + size, "%2d %14s%s\n",
			i, profile_name[i], (i == smu->power_profile_mode) ? "*" : " ");
	}

	return size;
}

static int yellow_carp_set_power_profile_mode(struct smu_context *smu,
						long *input, uint32_t size)
{
	int workload_type, ret;
	uint32_t profile_mode = input[size];

	if (profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {
		dev_err(smu->adev->dev, "Invalid power profile mode %d\n", profile_mode);
		return -EINVAL;
	}

	if (profile_mode == PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT ||
			profile_mode == PP_SMC_POWER_PROFILE_POWERSAVING)
		return 0;

	/* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
	workload_type = smu_cmn_to_asic_specific_index(smu,
						       CMN2ASIC_MAPPING_WORKLOAD,
						       profile_mode);
	if (workload_type < 0) {
		dev_dbg(smu->adev->dev, "Unsupported power profile mode %d on YELLOWCARP\n",
					profile_mode);
		return -EINVAL;
	}

	ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ActiveProcessNotify,
				    1 << workload_type,
				    NULL);
	if (ret) {
		dev_err_once(smu->adev->dev, "Fail to set workload type %d\n",
					workload_type);
		return ret;
	}

	smu->power_profile_mode = profile_mode;

	return 0;
}

static int yellow_carp_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABLE_COMMAND type,
					long input[], uint32_t size)
{
@@ -940,6 +1023,8 @@ static const struct pptable_funcs yellow_carp_ppt_funcs = {
	.read_sensor = yellow_carp_read_sensor,
	.is_dpm_running = yellow_carp_is_dpm_running,
	.set_watermarks_table = yellow_carp_set_watermarks_table,
	.get_power_profile_mode = yellow_carp_get_power_profile_mode,
	.set_power_profile_mode = yellow_carp_set_power_profile_mode,
	.get_enabled_mask = smu_cmn_get_enabled_32_bits_mask,
	.get_pp_feature_mask = smu_cmn_get_pp_feature_mask,
	.set_driver_table_location = smu_v13_0_1_set_driver_table_location,
@@ -958,5 +1043,6 @@ void yellow_carp_set_ppt_funcs(struct smu_context *smu)
	smu->message_map = yellow_carp_message_map;
	smu->feature_map = yellow_carp_feature_mask_map;
	smu->table_map = yellow_carp_table_map;
	smu->workload_map = yellow_carp_workload_map;
	smu->is_apu = true;
}