Commit d5c7255d authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/amdgpu/pm: fix powerplay OD interface

The overclocking interface currently appends data to a
string.  Revert back to using sprintf().

Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1774


Fixes: 6db0c87a ("amdgpu/pm: Replace hwmgr smu usage of sprintf with sysfs_emit")
Acked-by: default avatarEvan Quan <evan.quan@amd.com>
Acked-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
parent 57961c4c
Loading
Loading
Loading
Loading
+9 −11
Original line number Diff line number Diff line
@@ -1024,8 +1024,6 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr,
	uint32_t min_freq, max_freq = 0;
	uint32_t ret = 0;

	phm_get_sysfs_buf(&buf, &size);

	switch (type) {
	case PP_SCLK:
		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetGfxclkFrequency, &now);
@@ -1038,13 +1036,13 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr,
		else
			i = 1;

		size += sysfs_emit_at(buf, size, "0: %uMhz %s\n",
		size += sprintf(buf + size, "0: %uMhz %s\n",
					data->gfx_min_freq_limit/100,
					i == 0 ? "*" : "");
		size += sysfs_emit_at(buf, size, "1: %uMhz %s\n",
		size += sprintf(buf + size, "1: %uMhz %s\n",
					i == 1 ? now : SMU10_UMD_PSTATE_GFXCLK,
					i == 1 ? "*" : "");
		size += sysfs_emit_at(buf, size, "2: %uMhz %s\n",
		size += sprintf(buf + size, "2: %uMhz %s\n",
					data->gfx_max_freq_limit/100,
					i == 2 ? "*" : "");
		break;
@@ -1052,7 +1050,7 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr,
		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetFclkFrequency, &now);

		for (i = 0; i < mclk_table->count; i++)
			size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
			size += sprintf(buf + size, "%d: %uMhz %s\n",
					i,
					mclk_table->entries[i].clk / 100,
					((mclk_table->entries[i].clk / 100)
@@ -1067,10 +1065,10 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr,
			if (ret)
				return ret;

			size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK");
			size += sysfs_emit_at(buf, size, "0: %10uMhz\n",
			size += sprintf(buf + size, "%s:\n", "OD_SCLK");
			size += sprintf(buf + size, "0: %10uMhz\n",
			(data->gfx_actual_soft_min_freq > 0) ? data->gfx_actual_soft_min_freq : min_freq);
			size += sysfs_emit_at(buf, size, "1: %10uMhz\n",
			size += sprintf(buf + size, "1: %10uMhz\n",
			(data->gfx_actual_soft_max_freq > 0) ? data->gfx_actual_soft_max_freq : max_freq);
		}
		break;
@@ -1083,8 +1081,8 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr,
			if (ret)
				return ret;

			size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
			size += sysfs_emit_at(buf, size, "SCLK: %7uMHz %10uMHz\n",
			size += sprintf(buf + size, "%s:\n", "OD_RANGE");
			size += sprintf(buf + size, "SCLK: %7uMHz %10uMHz\n",
				min_freq, max_freq);
		}
		break;
+11 −13
Original line number Diff line number Diff line
@@ -4914,8 +4914,6 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr,
	int size = 0;
	uint32_t i, now, clock, pcie_speed;

	phm_get_sysfs_buf(&buf, &size);

	switch (type) {
	case PP_SCLK:
		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_API_GetSclkFrequency, &clock);
@@ -4928,7 +4926,7 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr,
		now = i;

		for (i = 0; i < sclk_table->count; i++)
			size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
			size += sprintf(buf + size, "%d: %uMhz %s\n",
					i, sclk_table->dpm_levels[i].value / 100,
					(i == now) ? "*" : "");
		break;
@@ -4943,7 +4941,7 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr,
		now = i;

		for (i = 0; i < mclk_table->count; i++)
			size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
			size += sprintf(buf + size, "%d: %uMhz %s\n",
					i, mclk_table->dpm_levels[i].value / 100,
					(i == now) ? "*" : "");
		break;
@@ -4957,7 +4955,7 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr,
		now = i;

		for (i = 0; i < pcie_table->count; i++)
			size += sysfs_emit_at(buf, size, "%d: %s %s\n", i,
			size += sprintf(buf + size, "%d: %s %s\n", i,
					(pcie_table->dpm_levels[i].value == 0) ? "2.5GT/s, x8" :
					(pcie_table->dpm_levels[i].value == 1) ? "5.0GT/s, x16" :
					(pcie_table->dpm_levels[i].value == 2) ? "8.0GT/s, x16" : "",
@@ -4965,32 +4963,32 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr,
		break;
	case OD_SCLK:
		if (hwmgr->od_enabled) {
			size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK");
			size += sprintf(buf + size, "%s:\n", "OD_SCLK");
			for (i = 0; i < odn_sclk_table->num_of_pl; i++)
				size += sysfs_emit_at(buf, size, "%d: %10uMHz %10umV\n",
				size += sprintf(buf + size, "%d: %10uMHz %10umV\n",
					i, odn_sclk_table->entries[i].clock/100,
					odn_sclk_table->entries[i].vddc);
		}
		break;
	case OD_MCLK:
		if (hwmgr->od_enabled) {
			size += sysfs_emit_at(buf, size, "%s:\n", "OD_MCLK");
			size += sprintf(buf + size, "%s:\n", "OD_MCLK");
			for (i = 0; i < odn_mclk_table->num_of_pl; i++)
				size += sysfs_emit_at(buf, size, "%d: %10uMHz %10umV\n",
				size += sprintf(buf + size, "%d: %10uMHz %10umV\n",
					i, odn_mclk_table->entries[i].clock/100,
					odn_mclk_table->entries[i].vddc);
		}
		break;
	case OD_RANGE:
		if (hwmgr->od_enabled) {
			size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
			size += sysfs_emit_at(buf, size, "SCLK: %7uMHz %10uMHz\n",
			size += sprintf(buf + size, "%s:\n", "OD_RANGE");
			size += sprintf(buf + size, "SCLK: %7uMHz %10uMHz\n",
				data->golden_dpm_table.sclk_table.dpm_levels[0].value/100,
				hwmgr->platform_descriptor.overdriveLimit.engineClock/100);
			size += sysfs_emit_at(buf, size, "MCLK: %7uMHz %10uMHz\n",
			size += sprintf(buf + size, "MCLK: %7uMHz %10uMHz\n",
				data->golden_dpm_table.mclk_table.dpm_levels[0].value/100,
				hwmgr->platform_descriptor.overdriveLimit.memoryClock/100);
			size += sysfs_emit_at(buf, size, "VDDC: %7umV %11umV\n",
			size += sprintf(buf + size, "VDDC: %7umV %11umV\n",
				data->odn_dpm_table.min_vddc,
				data->odn_dpm_table.max_vddc);
		}
+2 −4
Original line number Diff line number Diff line
@@ -1550,8 +1550,6 @@ static int smu8_print_clock_levels(struct pp_hwmgr *hwmgr,
	uint32_t i, now;
	int size = 0;

	phm_get_sysfs_buf(&buf, &size);

	switch (type) {
	case PP_SCLK:
		now = PHM_GET_FIELD(cgs_read_ind_register(hwmgr->device,
@@ -1561,7 +1559,7 @@ static int smu8_print_clock_levels(struct pp_hwmgr *hwmgr,
				CURR_SCLK_INDEX);

		for (i = 0; i < sclk_table->count; i++)
			size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
			size += sprintf(buf + size, "%d: %uMhz %s\n",
					i, sclk_table->entries[i].clk / 100,
					(i == now) ? "*" : "");
		break;
@@ -1573,7 +1571,7 @@ static int smu8_print_clock_levels(struct pp_hwmgr *hwmgr,
				CURR_MCLK_INDEX);

		for (i = SMU8_NUM_NBPMEMORYCLOCK; i > 0; i--)
			size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
			size += sprintf(buf + size, "%d: %uMhz %s\n",
					SMU8_NUM_NBPMEMORYCLOCK-i, data->sys_info.nbp_memory_clock[i-1] / 100,
					(SMU8_NUM_NBPMEMORYCLOCK-i == now) ? "*" : "");
		break;
+13 −15
Original line number Diff line number Diff line
@@ -4639,8 +4639,6 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,

	int i, now, size = 0, count = 0;

	phm_get_sysfs_buf(&buf, &size);

	switch (type) {
	case PP_SCLK:
		if (data->registry_data.sclk_dpm_key_disabled)
@@ -4654,7 +4652,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
		else
			count = sclk_table->count;
		for (i = 0; i < count; i++)
			size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
			size += sprintf(buf + size, "%d: %uMhz %s\n",
					i, sclk_table->dpm_levels[i].value / 100,
					(i == now) ? "*" : "");
		break;
@@ -4665,7 +4663,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentUclkIndex, &now);

		for (i = 0; i < mclk_table->count; i++)
			size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
			size += sprintf(buf + size, "%d: %uMhz %s\n",
					i, mclk_table->dpm_levels[i].value / 100,
					(i == now) ? "*" : "");
		break;
@@ -4676,7 +4674,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentSocclkIndex, &now);

		for (i = 0; i < soc_table->count; i++)
			size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
			size += sprintf(buf + size, "%d: %uMhz %s\n",
					i, soc_table->dpm_levels[i].value / 100,
					(i == now) ? "*" : "");
		break;
@@ -4688,7 +4686,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
				PPSMC_MSG_GetClockFreqMHz, CLK_DCEFCLK, &now);

		for (i = 0; i < dcef_table->count; i++)
			size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
			size += sprintf(buf + size, "%d: %uMhz %s\n",
					i, dcef_table->dpm_levels[i].value / 100,
					(dcef_table->dpm_levels[i].value / 100 == now) ?
					"*" : "");
@@ -4702,7 +4700,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
			gen_speed = pptable->PcieGenSpeed[i];
			lane_width = pptable->PcieLaneCount[i];

			size += sysfs_emit_at(buf, size, "%d: %s %s %s\n", i,
			size += sprintf(buf + size, "%d: %s %s %s\n", i,
					(gen_speed == 0) ? "2.5GT/s," :
					(gen_speed == 1) ? "5.0GT/s," :
					(gen_speed == 2) ? "8.0GT/s," :
@@ -4721,34 +4719,34 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,

	case OD_SCLK:
		if (hwmgr->od_enabled) {
			size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK");
			size += sprintf(buf + size, "%s:\n", "OD_SCLK");
			podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_sclk;
			for (i = 0; i < podn_vdd_dep->count; i++)
				size += sysfs_emit_at(buf, size, "%d: %10uMhz %10umV\n",
				size += sprintf(buf + size, "%d: %10uMhz %10umV\n",
					i, podn_vdd_dep->entries[i].clk / 100,
						podn_vdd_dep->entries[i].vddc);
		}
		break;
	case OD_MCLK:
		if (hwmgr->od_enabled) {
			size += sysfs_emit_at(buf, size, "%s:\n", "OD_MCLK");
			size += sprintf(buf + size, "%s:\n", "OD_MCLK");
			podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_mclk;
			for (i = 0; i < podn_vdd_dep->count; i++)
				size += sysfs_emit_at(buf, size, "%d: %10uMhz %10umV\n",
				size += sprintf(buf + size, "%d: %10uMhz %10umV\n",
					i, podn_vdd_dep->entries[i].clk/100,
						podn_vdd_dep->entries[i].vddc);
		}
		break;
	case OD_RANGE:
		if (hwmgr->od_enabled) {
			size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
			size += sysfs_emit_at(buf, size, "SCLK: %7uMHz %10uMHz\n",
			size += sprintf(buf + size, "%s:\n", "OD_RANGE");
			size += sprintf(buf + size, "SCLK: %7uMHz %10uMHz\n",
				data->golden_dpm_table.gfx_table.dpm_levels[0].value/100,
				hwmgr->platform_descriptor.overdriveLimit.engineClock/100);
			size += sysfs_emit_at(buf, size, "MCLK: %7uMHz %10uMHz\n",
			size += sprintf(buf + size, "MCLK: %7uMHz %10uMHz\n",
				data->golden_dpm_table.mem_table.dpm_levels[0].value/100,
				hwmgr->platform_descriptor.overdriveLimit.memoryClock/100);
			size += sysfs_emit_at(buf, size, "VDDC: %7umV %11umV\n",
			size += sprintf(buf + size, "VDDC: %7umV %11umV\n",
				data->odn_dpm_table.min_vddc,
				data->odn_dpm_table.max_vddc);
		}
+4 −6
Original line number Diff line number Diff line
@@ -2246,8 +2246,6 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr,
	int i, now, size = 0;
	struct pp_clock_levels_with_latency clocks;

	phm_get_sysfs_buf(&buf, &size);

	switch (type) {
	case PP_SCLK:
		PP_ASSERT_WITH_CODE(
@@ -2260,7 +2258,7 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr,
				"Attempt to get gfx clk levels Failed!",
				return -1);
		for (i = 0; i < clocks.num_levels; i++)
			size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
			size += sprintf(buf + size, "%d: %uMhz %s\n",
				i, clocks.data[i].clocks_in_khz / 1000,
				(clocks.data[i].clocks_in_khz / 1000 == now / 100) ? "*" : "");
		break;
@@ -2276,7 +2274,7 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr,
				"Attempt to get memory clk levels Failed!",
				return -1);
		for (i = 0; i < clocks.num_levels; i++)
			size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
			size += sprintf(buf + size, "%d: %uMhz %s\n",
				i, clocks.data[i].clocks_in_khz / 1000,
				(clocks.data[i].clocks_in_khz / 1000 == now / 100) ? "*" : "");
		break;
@@ -2294,7 +2292,7 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr,
				"Attempt to get soc clk levels Failed!",
				return -1);
		for (i = 0; i < clocks.num_levels; i++)
			size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
			size += sprintf(buf + size, "%d: %uMhz %s\n",
				i, clocks.data[i].clocks_in_khz / 1000,
				(clocks.data[i].clocks_in_khz / 1000 == now) ? "*" : "");
		break;
@@ -2312,7 +2310,7 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr,
				"Attempt to get dcef clk levels Failed!",
				return -1);
		for (i = 0; i < clocks.num_levels; i++)
			size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
			size += sprintf(buf + size, "%d: %uMhz %s\n",
				i, clocks.data[i].clocks_in_khz / 1000,
				(clocks.data[i].clocks_in_khz / 1000 == now) ? "*" : "");
		break;
Loading