1f7c1ed34SMikita Lipski /*
2f7c1ed34SMikita Lipski  * Copyright 2018 Advanced Micro Devices, Inc.
3f7c1ed34SMikita Lipski  *
4f7c1ed34SMikita Lipski  * Permission is hereby granted, free of charge, to any person obtaining a
5f7c1ed34SMikita Lipski  * copy of this software and associated documentation files (the "Software"),
6f7c1ed34SMikita Lipski  * to deal in the Software without restriction, including without limitation
7f7c1ed34SMikita Lipski  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8f7c1ed34SMikita Lipski  * and/or sell copies of the Software, and to permit persons to whom the
9f7c1ed34SMikita Lipski  * Software is furnished to do so, subject to the following conditions:
10f7c1ed34SMikita Lipski  *
11f7c1ed34SMikita Lipski  * The above copyright notice and this permission notice shall be included in
12f7c1ed34SMikita Lipski  * all copies or substantial portions of the Software.
13f7c1ed34SMikita Lipski  *
14f7c1ed34SMikita Lipski  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15f7c1ed34SMikita Lipski  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16f7c1ed34SMikita Lipski  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17f7c1ed34SMikita Lipski  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18f7c1ed34SMikita Lipski  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19f7c1ed34SMikita Lipski  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20f7c1ed34SMikita Lipski  * OTHER DEALINGS IN THE SOFTWARE.
21f7c1ed34SMikita Lipski  *
22f7c1ed34SMikita Lipski  * Authors: AMD
23f7c1ed34SMikita Lipski  */
24f7c1ed34SMikita Lipski #include <linux/string.h>
25f7c1ed34SMikita Lipski #include <linux/acpi.h>
26f7c1ed34SMikita Lipski 
27f7c1ed34SMikita Lipski #include <drm/drmP.h>
28fcd70cd3SDaniel Vetter #include <drm/drm_probe_helper.h>
29f7c1ed34SMikita Lipski #include <drm/amdgpu_drm.h>
30f7c1ed34SMikita Lipski #include "dm_services.h"
31f7c1ed34SMikita Lipski #include "amdgpu.h"
32f7c1ed34SMikita Lipski #include "amdgpu_dm.h"
33f7c1ed34SMikita Lipski #include "amdgpu_dm_irq.h"
34f7c1ed34SMikita Lipski #include "amdgpu_pm.h"
35f7c1ed34SMikita Lipski #include "dm_pp_smu.h"
3694ed6d0cSHuang Rui #include "amdgpu_smu.h"
37f7c1ed34SMikita Lipski 
38f7c1ed34SMikita Lipski 
39f7c1ed34SMikita Lipski bool dm_pp_apply_display_requirements(
40f7c1ed34SMikita Lipski 		const struct dc_context *ctx,
41f7c1ed34SMikita Lipski 		const struct dm_pp_display_configuration *pp_display_cfg)
42f7c1ed34SMikita Lipski {
43f7c1ed34SMikita Lipski 	struct amdgpu_device *adev = ctx->driver_context;
4494ed6d0cSHuang Rui 	struct smu_context *smu = &adev->smu;
45d4d5eaceSrex zhu 	int i;
46f7c1ed34SMikita Lipski 
47f7c1ed34SMikita Lipski 	if (adev->pm.dpm_enabled) {
48f7c1ed34SMikita Lipski 
49f7c1ed34SMikita Lipski 		memset(&adev->pm.pm_display_cfg, 0,
50f7c1ed34SMikita Lipski 				sizeof(adev->pm.pm_display_cfg));
51f7c1ed34SMikita Lipski 
52f7c1ed34SMikita Lipski 		adev->pm.pm_display_cfg.cpu_cc6_disable =
53f7c1ed34SMikita Lipski 			pp_display_cfg->cpu_cc6_disable;
54f7c1ed34SMikita Lipski 
55f7c1ed34SMikita Lipski 		adev->pm.pm_display_cfg.cpu_pstate_disable =
56f7c1ed34SMikita Lipski 			pp_display_cfg->cpu_pstate_disable;
57f7c1ed34SMikita Lipski 
58f7c1ed34SMikita Lipski 		adev->pm.pm_display_cfg.cpu_pstate_separation_time =
59f7c1ed34SMikita Lipski 			pp_display_cfg->cpu_pstate_separation_time;
60f7c1ed34SMikita Lipski 
61f7c1ed34SMikita Lipski 		adev->pm.pm_display_cfg.nb_pstate_switch_disable =
62f7c1ed34SMikita Lipski 			pp_display_cfg->nb_pstate_switch_disable;
63f7c1ed34SMikita Lipski 
64f7c1ed34SMikita Lipski 		adev->pm.pm_display_cfg.num_display =
65f7c1ed34SMikita Lipski 				pp_display_cfg->display_count;
66f7c1ed34SMikita Lipski 		adev->pm.pm_display_cfg.num_path_including_non_display =
67f7c1ed34SMikita Lipski 				pp_display_cfg->display_count;
68f7c1ed34SMikita Lipski 
69f7c1ed34SMikita Lipski 		adev->pm.pm_display_cfg.min_core_set_clock =
70f7c1ed34SMikita Lipski 				pp_display_cfg->min_engine_clock_khz/10;
71f7c1ed34SMikita Lipski 		adev->pm.pm_display_cfg.min_core_set_clock_in_sr =
72f7c1ed34SMikita Lipski 				pp_display_cfg->min_engine_clock_deep_sleep_khz/10;
73f7c1ed34SMikita Lipski 		adev->pm.pm_display_cfg.min_mem_set_clock =
74f7c1ed34SMikita Lipski 				pp_display_cfg->min_memory_clock_khz/10;
75f7c1ed34SMikita Lipski 
763180fb67Srex zhu 		adev->pm.pm_display_cfg.min_dcef_deep_sleep_set_clk =
773180fb67Srex zhu 				pp_display_cfg->min_engine_clock_deep_sleep_khz/10;
783180fb67Srex zhu 		adev->pm.pm_display_cfg.min_dcef_set_clk =
793180fb67Srex zhu 				pp_display_cfg->min_dcfclock_khz/10;
803180fb67Srex zhu 
81f7c1ed34SMikita Lipski 		adev->pm.pm_display_cfg.multi_monitor_in_sync =
82f7c1ed34SMikita Lipski 				pp_display_cfg->all_displays_in_sync;
83f7c1ed34SMikita Lipski 		adev->pm.pm_display_cfg.min_vblank_time =
84f7c1ed34SMikita Lipski 				pp_display_cfg->avail_mclk_switch_time_us;
85f7c1ed34SMikita Lipski 
86f7c1ed34SMikita Lipski 		adev->pm.pm_display_cfg.display_clk =
87f7c1ed34SMikita Lipski 				pp_display_cfg->disp_clk_khz/10;
88f7c1ed34SMikita Lipski 
89f7c1ed34SMikita Lipski 		adev->pm.pm_display_cfg.dce_tolerable_mclk_in_active_latency =
90f7c1ed34SMikita Lipski 				pp_display_cfg->avail_mclk_switch_time_in_disp_active_us;
91f7c1ed34SMikita Lipski 
92f7c1ed34SMikita Lipski 		adev->pm.pm_display_cfg.crtc_index = pp_display_cfg->crtc_index;
93f7c1ed34SMikita Lipski 		adev->pm.pm_display_cfg.line_time_in_us =
94f7c1ed34SMikita Lipski 				pp_display_cfg->line_time_in_us;
95f7c1ed34SMikita Lipski 
96f7c1ed34SMikita Lipski 		adev->pm.pm_display_cfg.vrefresh = pp_display_cfg->disp_configs[0].v_refresh;
97f7c1ed34SMikita Lipski 		adev->pm.pm_display_cfg.crossfire_display_index = -1;
98f7c1ed34SMikita Lipski 		adev->pm.pm_display_cfg.min_bus_bandwidth = 0;
99f7c1ed34SMikita Lipski 
100d4d5eaceSrex zhu 		for (i = 0; i < pp_display_cfg->display_count; i++) {
101d4d5eaceSrex zhu 			const struct dm_pp_single_disp_config *dc_cfg =
102d4d5eaceSrex zhu 						&pp_display_cfg->disp_configs[i];
103d4d5eaceSrex zhu 			adev->pm.pm_display_cfg.displays[i].controller_id = dc_cfg->pipe_idx + 1;
104d4d5eaceSrex zhu 		}
105d4d5eaceSrex zhu 
1066f059c64SRex Zhu 		if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->display_configuration_change)
107f7c1ed34SMikita Lipski 			adev->powerplay.pp_funcs->display_configuration_change(
108f7c1ed34SMikita Lipski 				adev->powerplay.pp_handle,
109f7c1ed34SMikita Lipski 				&adev->pm.pm_display_cfg);
11094ed6d0cSHuang Rui 		else
11194ed6d0cSHuang Rui 			smu_display_configuration_change(smu,
11294ed6d0cSHuang Rui 							 &adev->pm.pm_display_cfg);
11340d0ebd9SRex Zhu 
11440d0ebd9SRex Zhu 		amdgpu_pm_compute_clocks(adev);
115f7c1ed34SMikita Lipski 	}
116f7c1ed34SMikita Lipski 
117f7c1ed34SMikita Lipski 	return true;
118f7c1ed34SMikita Lipski }
119f7c1ed34SMikita Lipski 
120f7c1ed34SMikita Lipski static void get_default_clock_levels(
121f7c1ed34SMikita Lipski 		enum dm_pp_clock_type clk_type,
122f7c1ed34SMikita Lipski 		struct dm_pp_clock_levels *clks)
123f7c1ed34SMikita Lipski {
124f7c1ed34SMikita Lipski 	uint32_t disp_clks_in_khz[6] = {
125f7c1ed34SMikita Lipski 			300000, 400000, 496560, 626090, 685720, 757900 };
126f7c1ed34SMikita Lipski 	uint32_t sclks_in_khz[6] = {
127f7c1ed34SMikita Lipski 			300000, 360000, 423530, 514290, 626090, 720000 };
128f7c1ed34SMikita Lipski 	uint32_t mclks_in_khz[2] = { 333000, 800000 };
129f7c1ed34SMikita Lipski 
130f7c1ed34SMikita Lipski 	switch (clk_type) {
131f7c1ed34SMikita Lipski 	case DM_PP_CLOCK_TYPE_DISPLAY_CLK:
132f7c1ed34SMikita Lipski 		clks->num_levels = 6;
133f7c1ed34SMikita Lipski 		memmove(clks->clocks_in_khz, disp_clks_in_khz,
134f7c1ed34SMikita Lipski 				sizeof(disp_clks_in_khz));
135f7c1ed34SMikita Lipski 		break;
136f7c1ed34SMikita Lipski 	case DM_PP_CLOCK_TYPE_ENGINE_CLK:
137f7c1ed34SMikita Lipski 		clks->num_levels = 6;
138f7c1ed34SMikita Lipski 		memmove(clks->clocks_in_khz, sclks_in_khz,
139f7c1ed34SMikita Lipski 				sizeof(sclks_in_khz));
140f7c1ed34SMikita Lipski 		break;
141f7c1ed34SMikita Lipski 	case DM_PP_CLOCK_TYPE_MEMORY_CLK:
142f7c1ed34SMikita Lipski 		clks->num_levels = 2;
143f7c1ed34SMikita Lipski 		memmove(clks->clocks_in_khz, mclks_in_khz,
144f7c1ed34SMikita Lipski 				sizeof(mclks_in_khz));
145f7c1ed34SMikita Lipski 		break;
146f7c1ed34SMikita Lipski 	default:
147f7c1ed34SMikita Lipski 		clks->num_levels = 0;
148f7c1ed34SMikita Lipski 		break;
149f7c1ed34SMikita Lipski 	}
150f7c1ed34SMikita Lipski }
151f7c1ed34SMikita Lipski 
152a43913eaSKevin Wang static enum smu_clk_type dc_to_smu_clock_type(
153a43913eaSKevin Wang 		enum dm_pp_clock_type dm_pp_clk_type)
154a43913eaSKevin Wang {
155a43913eaSKevin Wang #define DCCLK_MAP_SMUCLK(dcclk, smuclk) \
156a43913eaSKevin Wang 	[dcclk] = smuclk
157a43913eaSKevin Wang 
158a43913eaSKevin Wang 	static int dc_clk_type_map[] = {
159a43913eaSKevin Wang 		DCCLK_MAP_SMUCLK(DM_PP_CLOCK_TYPE_DISPLAY_CLK,	SMU_DISPCLK),
160a43913eaSKevin Wang 		DCCLK_MAP_SMUCLK(DM_PP_CLOCK_TYPE_ENGINE_CLK,	SMU_GFXCLK),
161a43913eaSKevin Wang 		DCCLK_MAP_SMUCLK(DM_PP_CLOCK_TYPE_MEMORY_CLK,	SMU_MCLK),
162a43913eaSKevin Wang 		DCCLK_MAP_SMUCLK(DM_PP_CLOCK_TYPE_DCEFCLK,	SMU_DCEFCLK),
163a43913eaSKevin Wang 		DCCLK_MAP_SMUCLK(DM_PP_CLOCK_TYPE_SOCCLK,	SMU_SOCCLK),
164a43913eaSKevin Wang 	};
165a43913eaSKevin Wang 
166a43913eaSKevin Wang 	return dc_clk_type_map[dm_pp_clk_type];
167a43913eaSKevin Wang }
168a43913eaSKevin Wang 
169f7c1ed34SMikita Lipski static enum amd_pp_clock_type dc_to_pp_clock_type(
170f7c1ed34SMikita Lipski 		enum dm_pp_clock_type dm_pp_clk_type)
171f7c1ed34SMikita Lipski {
172f7c1ed34SMikita Lipski 	enum amd_pp_clock_type amd_pp_clk_type = 0;
173f7c1ed34SMikita Lipski 
174f7c1ed34SMikita Lipski 	switch (dm_pp_clk_type) {
175f7c1ed34SMikita Lipski 	case DM_PP_CLOCK_TYPE_DISPLAY_CLK:
176f7c1ed34SMikita Lipski 		amd_pp_clk_type = amd_pp_disp_clock;
177f7c1ed34SMikita Lipski 		break;
178f7c1ed34SMikita Lipski 	case DM_PP_CLOCK_TYPE_ENGINE_CLK:
179f7c1ed34SMikita Lipski 		amd_pp_clk_type = amd_pp_sys_clock;
180f7c1ed34SMikita Lipski 		break;
181f7c1ed34SMikita Lipski 	case DM_PP_CLOCK_TYPE_MEMORY_CLK:
182f7c1ed34SMikita Lipski 		amd_pp_clk_type = amd_pp_mem_clock;
183f7c1ed34SMikita Lipski 		break;
184f7c1ed34SMikita Lipski 	case DM_PP_CLOCK_TYPE_DCEFCLK:
185f7c1ed34SMikita Lipski 		amd_pp_clk_type  = amd_pp_dcef_clock;
186f7c1ed34SMikita Lipski 		break;
187f7c1ed34SMikita Lipski 	case DM_PP_CLOCK_TYPE_DCFCLK:
188f7c1ed34SMikita Lipski 		amd_pp_clk_type = amd_pp_dcf_clock;
189f7c1ed34SMikita Lipski 		break;
190f7c1ed34SMikita Lipski 	case DM_PP_CLOCK_TYPE_PIXELCLK:
191f7c1ed34SMikita Lipski 		amd_pp_clk_type = amd_pp_pixel_clock;
192f7c1ed34SMikita Lipski 		break;
193f7c1ed34SMikita Lipski 	case DM_PP_CLOCK_TYPE_FCLK:
194f7c1ed34SMikita Lipski 		amd_pp_clk_type = amd_pp_f_clock;
195f7c1ed34SMikita Lipski 		break;
196f7c1ed34SMikita Lipski 	case DM_PP_CLOCK_TYPE_DISPLAYPHYCLK:
19766917e56Srex zhu 		amd_pp_clk_type = amd_pp_phy_clock;
19866917e56Srex zhu 		break;
19966917e56Srex zhu 	case DM_PP_CLOCK_TYPE_DPPCLK:
200f7c1ed34SMikita Lipski 		amd_pp_clk_type = amd_pp_dpp_clock;
201f7c1ed34SMikita Lipski 		break;
202f7c1ed34SMikita Lipski 	default:
203f7c1ed34SMikita Lipski 		DRM_ERROR("DM_PPLIB: invalid clock type: %d!\n",
204f7c1ed34SMikita Lipski 				dm_pp_clk_type);
205f7c1ed34SMikita Lipski 		break;
206f7c1ed34SMikita Lipski 	}
207f7c1ed34SMikita Lipski 
208f7c1ed34SMikita Lipski 	return amd_pp_clk_type;
209f7c1ed34SMikita Lipski }
210f7c1ed34SMikita Lipski 
211c2c09ed5SMikita Lipski static enum dm_pp_clocks_state pp_to_dc_powerlevel_state(
212c2c09ed5SMikita Lipski 			enum PP_DAL_POWERLEVEL max_clocks_state)
213c2c09ed5SMikita Lipski {
214c2c09ed5SMikita Lipski 	switch (max_clocks_state) {
215c2c09ed5SMikita Lipski 	case PP_DAL_POWERLEVEL_0:
216c2c09ed5SMikita Lipski 		return DM_PP_CLOCKS_DPM_STATE_LEVEL_0;
217c2c09ed5SMikita Lipski 	case PP_DAL_POWERLEVEL_1:
218c2c09ed5SMikita Lipski 		return DM_PP_CLOCKS_DPM_STATE_LEVEL_1;
219c2c09ed5SMikita Lipski 	case PP_DAL_POWERLEVEL_2:
220c2c09ed5SMikita Lipski 		return DM_PP_CLOCKS_DPM_STATE_LEVEL_2;
221c2c09ed5SMikita Lipski 	case PP_DAL_POWERLEVEL_3:
222c2c09ed5SMikita Lipski 		return DM_PP_CLOCKS_DPM_STATE_LEVEL_3;
223c2c09ed5SMikita Lipski 	case PP_DAL_POWERLEVEL_4:
224c2c09ed5SMikita Lipski 		return DM_PP_CLOCKS_DPM_STATE_LEVEL_4;
225c2c09ed5SMikita Lipski 	case PP_DAL_POWERLEVEL_5:
226c2c09ed5SMikita Lipski 		return DM_PP_CLOCKS_DPM_STATE_LEVEL_5;
227c2c09ed5SMikita Lipski 	case PP_DAL_POWERLEVEL_6:
228c2c09ed5SMikita Lipski 		return DM_PP_CLOCKS_DPM_STATE_LEVEL_6;
229c2c09ed5SMikita Lipski 	case PP_DAL_POWERLEVEL_7:
230c2c09ed5SMikita Lipski 		return DM_PP_CLOCKS_DPM_STATE_LEVEL_7;
231c2c09ed5SMikita Lipski 	default:
232c2c09ed5SMikita Lipski 		DRM_ERROR("DM_PPLIB: invalid powerlevel state: %d!\n",
233c2c09ed5SMikita Lipski 				max_clocks_state);
234c2c09ed5SMikita Lipski 		return DM_PP_CLOCKS_STATE_INVALID;
235c2c09ed5SMikita Lipski 	}
236c2c09ed5SMikita Lipski }
237c2c09ed5SMikita Lipski 
238f7c1ed34SMikita Lipski static void pp_to_dc_clock_levels(
239f7c1ed34SMikita Lipski 		const struct amd_pp_clocks *pp_clks,
240f7c1ed34SMikita Lipski 		struct dm_pp_clock_levels *dc_clks,
241f7c1ed34SMikita Lipski 		enum dm_pp_clock_type dc_clk_type)
242f7c1ed34SMikita Lipski {
243f7c1ed34SMikita Lipski 	uint32_t i;
244f7c1ed34SMikita Lipski 
245f7c1ed34SMikita Lipski 	if (pp_clks->count > DM_PP_MAX_CLOCK_LEVELS) {
246f7c1ed34SMikita Lipski 		DRM_INFO("DM_PPLIB: Warning: %s clock: number of levels %d exceeds maximum of %d!\n",
247f7c1ed34SMikita Lipski 				DC_DECODE_PP_CLOCK_TYPE(dc_clk_type),
248f7c1ed34SMikita Lipski 				pp_clks->count,
249f7c1ed34SMikita Lipski 				DM_PP_MAX_CLOCK_LEVELS);
250f7c1ed34SMikita Lipski 
251f7c1ed34SMikita Lipski 		dc_clks->num_levels = DM_PP_MAX_CLOCK_LEVELS;
252f7c1ed34SMikita Lipski 	} else
253f7c1ed34SMikita Lipski 		dc_clks->num_levels = pp_clks->count;
254f7c1ed34SMikita Lipski 
255f7c1ed34SMikita Lipski 	DRM_INFO("DM_PPLIB: values for %s clock\n",
256f7c1ed34SMikita Lipski 			DC_DECODE_PP_CLOCK_TYPE(dc_clk_type));
257f7c1ed34SMikita Lipski 
258f7c1ed34SMikita Lipski 	for (i = 0; i < dc_clks->num_levels; i++) {
259f7c1ed34SMikita Lipski 		DRM_INFO("DM_PPLIB:\t %d\n", pp_clks->clock[i]);
26023ec3d14SRex Zhu 		dc_clks->clocks_in_khz[i] = pp_clks->clock[i];
261f7c1ed34SMikita Lipski 	}
262f7c1ed34SMikita Lipski }
263f7c1ed34SMikita Lipski 
264f7c1ed34SMikita Lipski static void pp_to_dc_clock_levels_with_latency(
265f7c1ed34SMikita Lipski 		const struct pp_clock_levels_with_latency *pp_clks,
266f7c1ed34SMikita Lipski 		struct dm_pp_clock_levels_with_latency *clk_level_info,
267f7c1ed34SMikita Lipski 		enum dm_pp_clock_type dc_clk_type)
268f7c1ed34SMikita Lipski {
269f7c1ed34SMikita Lipski 	uint32_t i;
270f7c1ed34SMikita Lipski 
271f7c1ed34SMikita Lipski 	if (pp_clks->num_levels > DM_PP_MAX_CLOCK_LEVELS) {
272f7c1ed34SMikita Lipski 		DRM_INFO("DM_PPLIB: Warning: %s clock: number of levels %d exceeds maximum of %d!\n",
273f7c1ed34SMikita Lipski 				DC_DECODE_PP_CLOCK_TYPE(dc_clk_type),
274f7c1ed34SMikita Lipski 				pp_clks->num_levels,
275f7c1ed34SMikita Lipski 				DM_PP_MAX_CLOCK_LEVELS);
276f7c1ed34SMikita Lipski 
277f7c1ed34SMikita Lipski 		clk_level_info->num_levels = DM_PP_MAX_CLOCK_LEVELS;
278f7c1ed34SMikita Lipski 	} else
279f7c1ed34SMikita Lipski 		clk_level_info->num_levels = pp_clks->num_levels;
280f7c1ed34SMikita Lipski 
281f7c1ed34SMikita Lipski 	DRM_DEBUG("DM_PPLIB: values for %s clock\n",
282f7c1ed34SMikita Lipski 			DC_DECODE_PP_CLOCK_TYPE(dc_clk_type));
283f7c1ed34SMikita Lipski 
284f7c1ed34SMikita Lipski 	for (i = 0; i < clk_level_info->num_levels; i++) {
28523ec3d14SRex Zhu 		DRM_DEBUG("DM_PPLIB:\t %d in kHz\n", pp_clks->data[i].clocks_in_khz);
28623ec3d14SRex Zhu 		clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz;
287f7c1ed34SMikita Lipski 		clk_level_info->data[i].latency_in_us = pp_clks->data[i].latency_in_us;
288f7c1ed34SMikita Lipski 	}
289f7c1ed34SMikita Lipski }
290f7c1ed34SMikita Lipski 
291f7c1ed34SMikita Lipski static void pp_to_dc_clock_levels_with_voltage(
292f7c1ed34SMikita Lipski 		const struct pp_clock_levels_with_voltage *pp_clks,
293f7c1ed34SMikita Lipski 		struct dm_pp_clock_levels_with_voltage *clk_level_info,
294f7c1ed34SMikita Lipski 		enum dm_pp_clock_type dc_clk_type)
295f7c1ed34SMikita Lipski {
296f7c1ed34SMikita Lipski 	uint32_t i;
297f7c1ed34SMikita Lipski 
298f7c1ed34SMikita Lipski 	if (pp_clks->num_levels > DM_PP_MAX_CLOCK_LEVELS) {
299f7c1ed34SMikita Lipski 		DRM_INFO("DM_PPLIB: Warning: %s clock: number of levels %d exceeds maximum of %d!\n",
300f7c1ed34SMikita Lipski 				DC_DECODE_PP_CLOCK_TYPE(dc_clk_type),
301f7c1ed34SMikita Lipski 				pp_clks->num_levels,
302f7c1ed34SMikita Lipski 				DM_PP_MAX_CLOCK_LEVELS);
303f7c1ed34SMikita Lipski 
304f7c1ed34SMikita Lipski 		clk_level_info->num_levels = DM_PP_MAX_CLOCK_LEVELS;
305f7c1ed34SMikita Lipski 	} else
306f7c1ed34SMikita Lipski 		clk_level_info->num_levels = pp_clks->num_levels;
307f7c1ed34SMikita Lipski 
308f7c1ed34SMikita Lipski 	DRM_INFO("DM_PPLIB: values for %s clock\n",
309f7c1ed34SMikita Lipski 			DC_DECODE_PP_CLOCK_TYPE(dc_clk_type));
310f7c1ed34SMikita Lipski 
311f7c1ed34SMikita Lipski 	for (i = 0; i < clk_level_info->num_levels; i++) {
31223ec3d14SRex Zhu 		DRM_INFO("DM_PPLIB:\t %d in kHz\n", pp_clks->data[i].clocks_in_khz);
31323ec3d14SRex Zhu 		clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz;
314f7c1ed34SMikita Lipski 		clk_level_info->data[i].voltage_in_mv = pp_clks->data[i].voltage_in_mv;
315f7c1ed34SMikita Lipski 	}
316f7c1ed34SMikita Lipski }
317f7c1ed34SMikita Lipski 
318f7c1ed34SMikita Lipski bool dm_pp_get_clock_levels_by_type(
319f7c1ed34SMikita Lipski 		const struct dc_context *ctx,
320f7c1ed34SMikita Lipski 		enum dm_pp_clock_type clk_type,
321f7c1ed34SMikita Lipski 		struct dm_pp_clock_levels *dc_clks)
322f7c1ed34SMikita Lipski {
323f7c1ed34SMikita Lipski 	struct amdgpu_device *adev = ctx->driver_context;
324f7c1ed34SMikita Lipski 	void *pp_handle = adev->powerplay.pp_handle;
325f7c1ed34SMikita Lipski 	struct amd_pp_clocks pp_clks = { 0 };
326f7c1ed34SMikita Lipski 	struct amd_pp_simple_clock_info validation_clks = { 0 };
327f7c1ed34SMikita Lipski 	uint32_t i;
328f7c1ed34SMikita Lipski 
3296f059c64SRex Zhu 	if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_clock_by_type) {
330f7c1ed34SMikita Lipski 		if (adev->powerplay.pp_funcs->get_clock_by_type(pp_handle,
331f7c1ed34SMikita Lipski 			dc_to_pp_clock_type(clk_type), &pp_clks)) {
332f7c1ed34SMikita Lipski 		/* Error in pplib. Provide default values. */
333b3ea88feSHuang Rui 			return true;
334b3ea88feSHuang Rui 		}
335b3ea88feSHuang Rui 	} else if (adev->smu.funcs && adev->smu.funcs->get_clock_by_type) {
336b3ea88feSHuang Rui 		if (smu_get_clock_by_type(&adev->smu,
337a43913eaSKevin Wang 					  dc_to_smu_clock_type(clk_type),
338b3ea88feSHuang Rui 					  &pp_clks)) {
339f7c1ed34SMikita Lipski 			get_default_clock_levels(clk_type, dc_clks);
340f7c1ed34SMikita Lipski 			return true;
341f7c1ed34SMikita Lipski 		}
342f7c1ed34SMikita Lipski 	}
343f7c1ed34SMikita Lipski 
344f7c1ed34SMikita Lipski 	pp_to_dc_clock_levels(&pp_clks, dc_clks, clk_type);
345f7c1ed34SMikita Lipski 
3466f059c64SRex Zhu 	if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_display_mode_validation_clocks) {
347f7c1ed34SMikita Lipski 		if (adev->powerplay.pp_funcs->get_display_mode_validation_clocks(
348f7c1ed34SMikita Lipski 						pp_handle, &validation_clks)) {
349f7c1ed34SMikita Lipski 			/* Error in pplib. Provide default values. */
350f7c1ed34SMikita Lipski 			DRM_INFO("DM_PPLIB: Warning: using default validation clocks!\n");
351f7c1ed34SMikita Lipski 			validation_clks.engine_max_clock = 72000;
352f7c1ed34SMikita Lipski 			validation_clks.memory_max_clock = 80000;
353f7c1ed34SMikita Lipski 			validation_clks.level = 0;
354f7c1ed34SMikita Lipski 		}
3556ec82684SHuang Rui 	} else if (adev->smu.funcs && adev->smu.funcs->get_max_high_clocks) {
3566ec82684SHuang Rui 		if (smu_get_max_high_clocks(&adev->smu, &validation_clks)) {
3576ec82684SHuang Rui 			DRM_INFO("DM_PPLIB: Warning: using default validation clocks!\n");
3586ec82684SHuang Rui 			validation_clks.engine_max_clock = 72000;
3596ec82684SHuang Rui 			validation_clks.memory_max_clock = 80000;
3606ec82684SHuang Rui 			validation_clks.level = 0;
3616ec82684SHuang Rui 		}
362f7c1ed34SMikita Lipski 	}
363f7c1ed34SMikita Lipski 
364f7c1ed34SMikita Lipski 	DRM_INFO("DM_PPLIB: Validation clocks:\n");
365f7c1ed34SMikita Lipski 	DRM_INFO("DM_PPLIB:    engine_max_clock: %d\n",
366f7c1ed34SMikita Lipski 			validation_clks.engine_max_clock);
367f7c1ed34SMikita Lipski 	DRM_INFO("DM_PPLIB:    memory_max_clock: %d\n",
368f7c1ed34SMikita Lipski 			validation_clks.memory_max_clock);
369f7c1ed34SMikita Lipski 	DRM_INFO("DM_PPLIB:    level           : %d\n",
370f7c1ed34SMikita Lipski 			validation_clks.level);
371f7c1ed34SMikita Lipski 
372f7c1ed34SMikita Lipski 	/* Translate 10 kHz to kHz. */
373f7c1ed34SMikita Lipski 	validation_clks.engine_max_clock *= 10;
374f7c1ed34SMikita Lipski 	validation_clks.memory_max_clock *= 10;
375f7c1ed34SMikita Lipski 
376f7c1ed34SMikita Lipski 	/* Determine the highest non-boosted level from the Validation Clocks */
377f7c1ed34SMikita Lipski 	if (clk_type == DM_PP_CLOCK_TYPE_ENGINE_CLK) {
378f7c1ed34SMikita Lipski 		for (i = 0; i < dc_clks->num_levels; i++) {
379f7c1ed34SMikita Lipski 			if (dc_clks->clocks_in_khz[i] > validation_clks.engine_max_clock) {
380f7c1ed34SMikita Lipski 				/* This clock is higher the validation clock.
381f7c1ed34SMikita Lipski 				 * Than means the previous one is the highest
382f7c1ed34SMikita Lipski 				 * non-boosted one. */
383f7c1ed34SMikita Lipski 				DRM_INFO("DM_PPLIB: reducing engine clock level from %d to %d\n",
384f7c1ed34SMikita Lipski 						dc_clks->num_levels, i);
385f7c1ed34SMikita Lipski 				dc_clks->num_levels = i > 0 ? i : 1;
386f7c1ed34SMikita Lipski 				break;
387f7c1ed34SMikita Lipski 			}
388f7c1ed34SMikita Lipski 		}
389f7c1ed34SMikita Lipski 	} else if (clk_type == DM_PP_CLOCK_TYPE_MEMORY_CLK) {
390f7c1ed34SMikita Lipski 		for (i = 0; i < dc_clks->num_levels; i++) {
391f7c1ed34SMikita Lipski 			if (dc_clks->clocks_in_khz[i] > validation_clks.memory_max_clock) {
392f7c1ed34SMikita Lipski 				DRM_INFO("DM_PPLIB: reducing memory clock level from %d to %d\n",
393f7c1ed34SMikita Lipski 						dc_clks->num_levels, i);
394f7c1ed34SMikita Lipski 				dc_clks->num_levels = i > 0 ? i : 1;
395f7c1ed34SMikita Lipski 				break;
396f7c1ed34SMikita Lipski 			}
397f7c1ed34SMikita Lipski 		}
398f7c1ed34SMikita Lipski 	}
399f7c1ed34SMikita Lipski 
400f7c1ed34SMikita Lipski 	return true;
401f7c1ed34SMikita Lipski }
402f7c1ed34SMikita Lipski 
403f7c1ed34SMikita Lipski bool dm_pp_get_clock_levels_by_type_with_latency(
404f7c1ed34SMikita Lipski 	const struct dc_context *ctx,
405f7c1ed34SMikita Lipski 	enum dm_pp_clock_type clk_type,
406f7c1ed34SMikita Lipski 	struct dm_pp_clock_levels_with_latency *clk_level_info)
407f7c1ed34SMikita Lipski {
408f7c1ed34SMikita Lipski 	struct amdgpu_device *adev = ctx->driver_context;
409f7c1ed34SMikita Lipski 	void *pp_handle = adev->powerplay.pp_handle;
410f7c1ed34SMikita Lipski 	struct pp_clock_levels_with_latency pp_clks = { 0 };
411f7c1ed34SMikita Lipski 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
412e5e4e223SHuang Rui 	int ret;
413f7c1ed34SMikita Lipski 
414e5e4e223SHuang Rui 	if (pp_funcs && pp_funcs->get_clock_by_type_with_latency) {
415e5e4e223SHuang Rui 		ret = pp_funcs->get_clock_by_type_with_latency(pp_handle,
416e5e4e223SHuang Rui 						dc_to_pp_clock_type(clk_type),
417e5e4e223SHuang Rui 						&pp_clks);
418e5e4e223SHuang Rui 		if (ret)
419f7c1ed34SMikita Lipski 			return false;
420e5e4e223SHuang Rui 	} else if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->get_clock_by_type_with_latency) {
421e5e4e223SHuang Rui 		if (smu_get_clock_by_type_with_latency(&adev->smu,
422f7c1ed34SMikita Lipski 						       dc_to_pp_clock_type(clk_type),
423f7c1ed34SMikita Lipski 						       &pp_clks))
424f7c1ed34SMikita Lipski 			return false;
425e5e4e223SHuang Rui 	}
426e5e4e223SHuang Rui 
427f7c1ed34SMikita Lipski 
428f7c1ed34SMikita Lipski 	pp_to_dc_clock_levels_with_latency(&pp_clks, clk_level_info, clk_type);
429f7c1ed34SMikita Lipski 
430f7c1ed34SMikita Lipski 	return true;
431f7c1ed34SMikita Lipski }
432f7c1ed34SMikita Lipski 
433f7c1ed34SMikita Lipski bool dm_pp_get_clock_levels_by_type_with_voltage(
434f7c1ed34SMikita Lipski 	const struct dc_context *ctx,
435f7c1ed34SMikita Lipski 	enum dm_pp_clock_type clk_type,
436f7c1ed34SMikita Lipski 	struct dm_pp_clock_levels_with_voltage *clk_level_info)
437f7c1ed34SMikita Lipski {
438f7c1ed34SMikita Lipski 	struct amdgpu_device *adev = ctx->driver_context;
439f7c1ed34SMikita Lipski 	void *pp_handle = adev->powerplay.pp_handle;
440f7c1ed34SMikita Lipski 	struct pp_clock_levels_with_voltage pp_clk_info = {0};
441f7c1ed34SMikita Lipski 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
4421e33d4d4SHuang Rui 	int ret;
443f7c1ed34SMikita Lipski 
4441e33d4d4SHuang Rui 	if (pp_funcs && pp_funcs->get_clock_by_type_with_voltage) {
4451e33d4d4SHuang Rui 		ret = pp_funcs->get_clock_by_type_with_voltage(pp_handle,
4461e33d4d4SHuang Rui 						dc_to_pp_clock_type(clk_type),
4471e33d4d4SHuang Rui 						&pp_clk_info);
4481e33d4d4SHuang Rui 		if (ret)
4496f059c64SRex Zhu 			return false;
4501e33d4d4SHuang Rui 	} else if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->get_clock_by_type_with_voltage) {
4511e33d4d4SHuang Rui 		if (smu_get_clock_by_type_with_voltage(&adev->smu,
452f7c1ed34SMikita Lipski 						       dc_to_pp_clock_type(clk_type),
453f7c1ed34SMikita Lipski 						       &pp_clk_info))
454f7c1ed34SMikita Lipski 			return false;
4551e33d4d4SHuang Rui 	}
456f7c1ed34SMikita Lipski 
457f7c1ed34SMikita Lipski 	pp_to_dc_clock_levels_with_voltage(&pp_clk_info, clk_level_info, clk_type);
458f7c1ed34SMikita Lipski 
459f7c1ed34SMikita Lipski 	return true;
460f7c1ed34SMikita Lipski }
461f7c1ed34SMikita Lipski 
462f7c1ed34SMikita Lipski bool dm_pp_notify_wm_clock_changes(
463f7c1ed34SMikita Lipski 	const struct dc_context *ctx,
464f7c1ed34SMikita Lipski 	struct dm_pp_wm_sets_with_clock_ranges *wm_with_clock_ranges)
465f7c1ed34SMikita Lipski {
466f7c1ed34SMikita Lipski 	/* TODO: to be implemented */
467f7c1ed34SMikita Lipski 	return false;
468f7c1ed34SMikita Lipski }
469f7c1ed34SMikita Lipski 
470f7c1ed34SMikita Lipski bool dm_pp_apply_power_level_change_request(
471f7c1ed34SMikita Lipski 	const struct dc_context *ctx,
472f7c1ed34SMikita Lipski 	struct dm_pp_power_level_change_request *level_change_req)
473f7c1ed34SMikita Lipski {
474f7c1ed34SMikita Lipski 	/* TODO: to be implemented */
475f7c1ed34SMikita Lipski 	return false;
476f7c1ed34SMikita Lipski }
477f7c1ed34SMikita Lipski 
478f7c1ed34SMikita Lipski bool dm_pp_apply_clock_for_voltage_request(
479f7c1ed34SMikita Lipski 	const struct dc_context *ctx,
480f7c1ed34SMikita Lipski 	struct dm_pp_clock_for_voltage_req *clock_for_voltage_req)
481f7c1ed34SMikita Lipski {
482f7c1ed34SMikita Lipski 	struct amdgpu_device *adev = ctx->driver_context;
483f7c1ed34SMikita Lipski 	struct pp_display_clock_request pp_clock_request = {0};
484f7c1ed34SMikita Lipski 	int ret = 0;
485f7c1ed34SMikita Lipski 
486f7c1ed34SMikita Lipski 	pp_clock_request.clock_type = dc_to_pp_clock_type(clock_for_voltage_req->clk_type);
487f7c1ed34SMikita Lipski 	pp_clock_request.clock_freq_in_khz = clock_for_voltage_req->clocks_in_khz;
488f7c1ed34SMikita Lipski 
489f7c1ed34SMikita Lipski 	if (!pp_clock_request.clock_type)
490f7c1ed34SMikita Lipski 		return false;
491f7c1ed34SMikita Lipski 
4926f059c64SRex Zhu 	if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->display_clock_voltage_request)
493f7c1ed34SMikita Lipski 		ret = adev->powerplay.pp_funcs->display_clock_voltage_request(
494f7c1ed34SMikita Lipski 			adev->powerplay.pp_handle,
495f7c1ed34SMikita Lipski 			&pp_clock_request);
49604885368SHuang Rui 	else if (adev->smu.funcs &&
49704885368SHuang Rui 		 adev->smu.funcs->display_clock_voltage_request)
49804885368SHuang Rui 		ret = smu_display_clock_voltage_request(&adev->smu,
49904885368SHuang Rui 							&pp_clock_request);
500f7c1ed34SMikita Lipski 	if (ret)
501f7c1ed34SMikita Lipski 		return false;
502f7c1ed34SMikita Lipski 	return true;
503f7c1ed34SMikita Lipski }
504f7c1ed34SMikita Lipski 
505f7c1ed34SMikita Lipski bool dm_pp_get_static_clocks(
506f7c1ed34SMikita Lipski 	const struct dc_context *ctx,
507f7c1ed34SMikita Lipski 	struct dm_pp_static_clock_info *static_clk_info)
508f7c1ed34SMikita Lipski {
509f7c1ed34SMikita Lipski 	struct amdgpu_device *adev = ctx->driver_context;
510f7c1ed34SMikita Lipski 	struct amd_pp_clock_info pp_clk_info = {0};
511f7c1ed34SMikita Lipski 	int ret = 0;
512f7c1ed34SMikita Lipski 
5136f059c64SRex Zhu 	if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_current_clocks)
514f7c1ed34SMikita Lipski 		ret = adev->powerplay.pp_funcs->get_current_clocks(
515f7c1ed34SMikita Lipski 			adev->powerplay.pp_handle,
516f7c1ed34SMikita Lipski 			&pp_clk_info);
5175e2d3881SHuang Rui 	else if (adev->smu.funcs)
5185e2d3881SHuang Rui 		ret = smu_get_current_clocks(&adev->smu, &pp_clk_info);
519f7c1ed34SMikita Lipski 	if (ret)
520f7c1ed34SMikita Lipski 		return false;
521f7c1ed34SMikita Lipski 
522c2c09ed5SMikita Lipski 	static_clk_info->max_clocks_state = pp_to_dc_powerlevel_state(pp_clk_info.max_clocks_state);
5233dbd823eSRex Zhu 	static_clk_info->max_mclk_khz = pp_clk_info.max_memory_clock * 10;
5243dbd823eSRex Zhu 	static_clk_info->max_sclk_khz = pp_clk_info.max_engine_clock * 10;
525f7c1ed34SMikita Lipski 
526f7c1ed34SMikita Lipski 	return true;
527f7c1ed34SMikita Lipski }
528f7c1ed34SMikita Lipski 
529f7c1ed34SMikita Lipski void pp_rv_set_wm_ranges(struct pp_smu *pp,
530f7c1ed34SMikita Lipski 		struct pp_smu_wm_range_sets *ranges)
531f7c1ed34SMikita Lipski {
532265f5ba6SJun Lei 	const struct dc_context *ctx = pp->dm;
533b0a634acSRex Zhu 	struct amdgpu_device *adev = ctx->driver_context;
534b0a634acSRex Zhu 	void *pp_handle = adev->powerplay.pp_handle;
535b0a634acSRex Zhu 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
536b0a634acSRex Zhu 	struct dm_pp_wm_sets_with_clock_ranges_soc15 wm_with_clock_ranges;
537b0a634acSRex Zhu 	struct dm_pp_clock_range_for_dmif_wm_set_soc15 *wm_dce_clocks = wm_with_clock_ranges.wm_dmif_clocks_ranges;
538b0a634acSRex Zhu 	struct dm_pp_clock_range_for_mcif_wm_set_soc15 *wm_soc_clocks = wm_with_clock_ranges.wm_mcif_clocks_ranges;
539b0a634acSRex Zhu 	int32_t i;
540f7c1ed34SMikita Lipski 
541b0a634acSRex Zhu 	wm_with_clock_ranges.num_wm_dmif_sets = ranges->num_reader_wm_sets;
542b0a634acSRex Zhu 	wm_with_clock_ranges.num_wm_mcif_sets = ranges->num_writer_wm_sets;
543f7c1ed34SMikita Lipski 
544b0a634acSRex Zhu 	for (i = 0; i < wm_with_clock_ranges.num_wm_dmif_sets; i++) {
545f7c1ed34SMikita Lipski 		if (ranges->reader_wm_sets[i].wm_inst > 3)
546b0a634acSRex Zhu 			wm_dce_clocks[i].wm_set_id = WM_SET_A;
547f7c1ed34SMikita Lipski 		else
548b0a634acSRex Zhu 			wm_dce_clocks[i].wm_set_id =
549f7c1ed34SMikita Lipski 					ranges->reader_wm_sets[i].wm_inst;
550b0a634acSRex Zhu 		wm_dce_clocks[i].wm_max_dcfclk_clk_in_khz =
551ba7b267aSFatemeh Darbehani 				ranges->reader_wm_sets[i].max_drain_clk_mhz * 1000;
552b0a634acSRex Zhu 		wm_dce_clocks[i].wm_min_dcfclk_clk_in_khz =
553ba7b267aSFatemeh Darbehani 				ranges->reader_wm_sets[i].min_drain_clk_mhz * 1000;
554b0a634acSRex Zhu 		wm_dce_clocks[i].wm_max_mem_clk_in_khz =
555ba7b267aSFatemeh Darbehani 				ranges->reader_wm_sets[i].max_fill_clk_mhz * 1000;
556b0a634acSRex Zhu 		wm_dce_clocks[i].wm_min_mem_clk_in_khz =
557ba7b267aSFatemeh Darbehani 				ranges->reader_wm_sets[i].min_fill_clk_mhz * 1000;
558f7c1ed34SMikita Lipski 	}
559f7c1ed34SMikita Lipski 
560b0a634acSRex Zhu 	for (i = 0; i < wm_with_clock_ranges.num_wm_mcif_sets; i++) {
561f7c1ed34SMikita Lipski 		if (ranges->writer_wm_sets[i].wm_inst > 3)
562b0a634acSRex Zhu 			wm_soc_clocks[i].wm_set_id = WM_SET_A;
563f7c1ed34SMikita Lipski 		else
564b0a634acSRex Zhu 			wm_soc_clocks[i].wm_set_id =
565f7c1ed34SMikita Lipski 					ranges->writer_wm_sets[i].wm_inst;
566b0a634acSRex Zhu 		wm_soc_clocks[i].wm_max_socclk_clk_in_khz =
567ba7b267aSFatemeh Darbehani 				ranges->writer_wm_sets[i].max_fill_clk_mhz * 1000;
568b0a634acSRex Zhu 		wm_soc_clocks[i].wm_min_socclk_clk_in_khz =
569ba7b267aSFatemeh Darbehani 				ranges->writer_wm_sets[i].min_fill_clk_mhz * 1000;
570b0a634acSRex Zhu 		wm_soc_clocks[i].wm_max_mem_clk_in_khz =
571ba7b267aSFatemeh Darbehani 				ranges->writer_wm_sets[i].max_drain_clk_mhz * 1000;
572b0a634acSRex Zhu 		wm_soc_clocks[i].wm_min_mem_clk_in_khz =
573ba7b267aSFatemeh Darbehani 				ranges->writer_wm_sets[i].min_drain_clk_mhz * 1000;
574f7c1ed34SMikita Lipski 	}
575f7c1ed34SMikita Lipski 
5762e069391SHuang Rui 	if (pp_funcs && pp_funcs->set_watermarks_for_clocks_ranges)
5772e069391SHuang Rui 		pp_funcs->set_watermarks_for_clocks_ranges(pp_handle,
5782e069391SHuang Rui 							   &wm_with_clock_ranges);
5792e069391SHuang Rui 	else if (adev->smu.funcs &&
5802e069391SHuang Rui 		 adev->smu.funcs->set_watermarks_for_clock_ranges)
5812e069391SHuang Rui 		smu_set_watermarks_for_clock_ranges(&adev->smu,
5822e069391SHuang Rui 						    &wm_with_clock_ranges);
583f7c1ed34SMikita Lipski }
584f7c1ed34SMikita Lipski 
585f7c1ed34SMikita Lipski void pp_rv_set_pme_wa_enable(struct pp_smu *pp)
586f7c1ed34SMikita Lipski {
587265f5ba6SJun Lei 	const struct dc_context *ctx = pp->dm;
588b0a634acSRex Zhu 	struct amdgpu_device *adev = ctx->driver_context;
589b0a634acSRex Zhu 	void *pp_handle = adev->powerplay.pp_handle;
590b0a634acSRex Zhu 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
591f7c1ed34SMikita Lipski 
592367eeed4SHuang Rui 	if (pp_funcs && pp_funcs->notify_smu_enable_pwe)
593b0a634acSRex Zhu 		pp_funcs->notify_smu_enable_pwe(pp_handle);
594367eeed4SHuang Rui 	else if (adev->smu.funcs)
595367eeed4SHuang Rui 		smu_notify_smu_enable_pwe(&adev->smu);
596f7c1ed34SMikita Lipski }
597f7c1ed34SMikita Lipski 
598588715bdShersen wu void pp_rv_set_active_display_count(struct pp_smu *pp, int count)
599588715bdShersen wu {
600588715bdShersen wu 	const struct dc_context *ctx = pp->dm;
601588715bdShersen wu 	struct amdgpu_device *adev = ctx->driver_context;
602588715bdShersen wu 	void *pp_handle = adev->powerplay.pp_handle;
603588715bdShersen wu 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
604588715bdShersen wu 
605588715bdShersen wu 	if (!pp_funcs || !pp_funcs->set_active_display_count)
606588715bdShersen wu 		return;
607588715bdShersen wu 
608588715bdShersen wu 	pp_funcs->set_active_display_count(pp_handle, count);
609588715bdShersen wu }
610588715bdShersen wu 
611588715bdShersen wu void pp_rv_set_min_deep_sleep_dcfclk(struct pp_smu *pp, int clock)
612588715bdShersen wu {
613588715bdShersen wu 	const struct dc_context *ctx = pp->dm;
614588715bdShersen wu 	struct amdgpu_device *adev = ctx->driver_context;
615588715bdShersen wu 	void *pp_handle = adev->powerplay.pp_handle;
616588715bdShersen wu 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
617588715bdShersen wu 
618588715bdShersen wu 	if (!pp_funcs || !pp_funcs->set_min_deep_sleep_dcefclk)
619588715bdShersen wu 		return;
620588715bdShersen wu 
621588715bdShersen wu 	pp_funcs->set_min_deep_sleep_dcefclk(pp_handle, clock);
622588715bdShersen wu }
623588715bdShersen wu 
624588715bdShersen wu void pp_rv_set_hard_min_dcefclk_by_freq(struct pp_smu *pp, int clock)
625588715bdShersen wu {
626588715bdShersen wu 	const struct dc_context *ctx = pp->dm;
627588715bdShersen wu 	struct amdgpu_device *adev = ctx->driver_context;
628588715bdShersen wu 	void *pp_handle = adev->powerplay.pp_handle;
629588715bdShersen wu 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
630588715bdShersen wu 
631588715bdShersen wu 	if (!pp_funcs || !pp_funcs->set_hard_min_dcefclk_by_freq)
632588715bdShersen wu 		return;
633588715bdShersen wu 
634588715bdShersen wu 	pp_funcs->set_hard_min_dcefclk_by_freq(pp_handle, clock);
635588715bdShersen wu }
636588715bdShersen wu 
637588715bdShersen wu void pp_rv_set_hard_min_fclk_by_freq(struct pp_smu *pp, int mhz)
638588715bdShersen wu {
639588715bdShersen wu 	const struct dc_context *ctx = pp->dm;
640588715bdShersen wu 	struct amdgpu_device *adev = ctx->driver_context;
641588715bdShersen wu 	void *pp_handle = adev->powerplay.pp_handle;
642588715bdShersen wu 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
643588715bdShersen wu 
644588715bdShersen wu 	if (!pp_funcs || !pp_funcs->set_hard_min_fclk_by_freq)
645588715bdShersen wu 		return;
646588715bdShersen wu 
647588715bdShersen wu 	pp_funcs->set_hard_min_fclk_by_freq(pp_handle, mhz);
648588715bdShersen wu }
649588715bdShersen wu 
65079a7b060Shersen wu enum pp_smu_status pp_nv_set_wm_ranges(struct pp_smu *pp,
65179a7b060Shersen wu 		struct pp_smu_wm_range_sets *ranges)
65279a7b060Shersen wu {
65379a7b060Shersen wu 	const struct dc_context *ctx = pp->dm;
65479a7b060Shersen wu 	struct amdgpu_device *adev = ctx->driver_context;
65579a7b060Shersen wu 	struct smu_context *smu = &adev->smu;
65679a7b060Shersen wu 	struct dm_pp_wm_sets_with_clock_ranges_soc15 wm_with_clock_ranges;
65779a7b060Shersen wu 	struct dm_pp_clock_range_for_dmif_wm_set_soc15 *wm_dce_clocks =
65879a7b060Shersen wu 			wm_with_clock_ranges.wm_dmif_clocks_ranges;
65979a7b060Shersen wu 	struct dm_pp_clock_range_for_mcif_wm_set_soc15 *wm_soc_clocks =
66079a7b060Shersen wu 			wm_with_clock_ranges.wm_mcif_clocks_ranges;
66179a7b060Shersen wu 	int32_t i;
66279a7b060Shersen wu 
66379a7b060Shersen wu 	wm_with_clock_ranges.num_wm_dmif_sets = ranges->num_reader_wm_sets;
66479a7b060Shersen wu 	wm_with_clock_ranges.num_wm_mcif_sets = ranges->num_writer_wm_sets;
66579a7b060Shersen wu 
66679a7b060Shersen wu 	for (i = 0; i < wm_with_clock_ranges.num_wm_dmif_sets; i++) {
66779a7b060Shersen wu 		if (ranges->reader_wm_sets[i].wm_inst > 3)
66879a7b060Shersen wu 			wm_dce_clocks[i].wm_set_id = WM_SET_A;
66979a7b060Shersen wu 		else
67079a7b060Shersen wu 			wm_dce_clocks[i].wm_set_id =
67179a7b060Shersen wu 					ranges->reader_wm_sets[i].wm_inst;
67279a7b060Shersen wu 		wm_dce_clocks[i].wm_max_dcfclk_clk_in_khz =
67379a7b060Shersen wu 			ranges->reader_wm_sets[i].max_drain_clk_mhz * 1000;
67479a7b060Shersen wu 		wm_dce_clocks[i].wm_min_dcfclk_clk_in_khz =
67579a7b060Shersen wu 			ranges->reader_wm_sets[i].min_drain_clk_mhz * 1000;
67679a7b060Shersen wu 		wm_dce_clocks[i].wm_max_mem_clk_in_khz =
67779a7b060Shersen wu 			ranges->reader_wm_sets[i].max_fill_clk_mhz * 1000;
67879a7b060Shersen wu 		wm_dce_clocks[i].wm_min_mem_clk_in_khz =
67979a7b060Shersen wu 			ranges->reader_wm_sets[i].min_fill_clk_mhz * 1000;
68079a7b060Shersen wu 	}
68179a7b060Shersen wu 
68279a7b060Shersen wu 	for (i = 0; i < wm_with_clock_ranges.num_wm_mcif_sets; i++) {
68379a7b060Shersen wu 		if (ranges->writer_wm_sets[i].wm_inst > 3)
68479a7b060Shersen wu 			wm_soc_clocks[i].wm_set_id = WM_SET_A;
68579a7b060Shersen wu 		else
68679a7b060Shersen wu 			wm_soc_clocks[i].wm_set_id =
68779a7b060Shersen wu 					ranges->writer_wm_sets[i].wm_inst;
68879a7b060Shersen wu 		wm_soc_clocks[i].wm_max_socclk_clk_in_khz =
68979a7b060Shersen wu 			ranges->writer_wm_sets[i].max_fill_clk_mhz * 1000;
69079a7b060Shersen wu 		wm_soc_clocks[i].wm_min_socclk_clk_in_khz =
69179a7b060Shersen wu 			ranges->writer_wm_sets[i].min_fill_clk_mhz * 1000;
69279a7b060Shersen wu 		wm_soc_clocks[i].wm_max_mem_clk_in_khz =
69379a7b060Shersen wu 			ranges->writer_wm_sets[i].max_drain_clk_mhz * 1000;
69479a7b060Shersen wu 		wm_soc_clocks[i].wm_min_mem_clk_in_khz =
69579a7b060Shersen wu 			ranges->writer_wm_sets[i].min_drain_clk_mhz * 1000;
69679a7b060Shersen wu 	}
69779a7b060Shersen wu 
69879a7b060Shersen wu 	if (!smu->funcs)
69979a7b060Shersen wu 		return PP_SMU_RESULT_UNSUPPORTED;
70079a7b060Shersen wu 
70179a7b060Shersen wu 	/* 0: successful or smu.funcs->set_watermarks_for_clock_ranges = NULL;
70279a7b060Shersen wu 	 * 1: fail
70379a7b060Shersen wu 	 */
70479a7b060Shersen wu 	if (smu_set_watermarks_for_clock_ranges(&adev->smu,
70579a7b060Shersen wu 			&wm_with_clock_ranges))
70679a7b060Shersen wu 		return PP_SMU_RESULT_UNSUPPORTED;
70779a7b060Shersen wu 
70879a7b060Shersen wu 	return PP_SMU_RESULT_OK;
70979a7b060Shersen wu }
71079a7b060Shersen wu 
71179a7b060Shersen wu enum pp_smu_status pp_nv_set_pme_wa_enable(struct pp_smu *pp)
71279a7b060Shersen wu {
71379a7b060Shersen wu 	const struct dc_context *ctx = pp->dm;
71479a7b060Shersen wu 	struct amdgpu_device *adev = ctx->driver_context;
71579a7b060Shersen wu 	struct smu_context *smu = &adev->smu;
71679a7b060Shersen wu 
71779a7b060Shersen wu 	if (!smu->funcs)
71879a7b060Shersen wu 		return PP_SMU_RESULT_UNSUPPORTED;
71979a7b060Shersen wu 
72079a7b060Shersen wu 	/* 0: successful or smu.funcs->set_azalia_d3_pme = NULL;  1: fail */
72179a7b060Shersen wu 	if (smu_set_azalia_d3_pme(smu))
72279a7b060Shersen wu 		return PP_SMU_RESULT_FAIL;
72379a7b060Shersen wu 
72479a7b060Shersen wu 	return PP_SMU_RESULT_OK;
72579a7b060Shersen wu }
72679a7b060Shersen wu 
72779a7b060Shersen wu enum pp_smu_status pp_nv_set_display_count(struct pp_smu *pp, int count)
72879a7b060Shersen wu {
72979a7b060Shersen wu 	const struct dc_context *ctx = pp->dm;
73079a7b060Shersen wu 	struct amdgpu_device *adev = ctx->driver_context;
73179a7b060Shersen wu 	struct smu_context *smu = &adev->smu;
73279a7b060Shersen wu 
73379a7b060Shersen wu 	if (!smu->funcs)
73479a7b060Shersen wu 		return PP_SMU_RESULT_UNSUPPORTED;
73579a7b060Shersen wu 
73679a7b060Shersen wu 	/* 0: successful or smu.funcs->set_display_count = NULL;  1: fail */
73779a7b060Shersen wu 	if (smu_set_display_count(smu, count))
73879a7b060Shersen wu 		return PP_SMU_RESULT_FAIL;
73979a7b060Shersen wu 
74079a7b060Shersen wu 	return PP_SMU_RESULT_OK;
74179a7b060Shersen wu }
74279a7b060Shersen wu 
74379a7b060Shersen wu enum pp_smu_status pp_nv_set_min_deep_sleep_dcfclk(struct pp_smu *pp, int mhz)
74479a7b060Shersen wu {
74579a7b060Shersen wu 	const struct dc_context *ctx = pp->dm;
74679a7b060Shersen wu 	struct amdgpu_device *adev = ctx->driver_context;
74779a7b060Shersen wu 	struct smu_context *smu = &adev->smu;
74879a7b060Shersen wu 
74979a7b060Shersen wu 	if (!smu->funcs)
75079a7b060Shersen wu 		return PP_SMU_RESULT_UNSUPPORTED;
75179a7b060Shersen wu 
75279a7b060Shersen wu 	/* 0: successful or smu.funcs->set_deep_sleep_dcefclk = NULL;1: fail */
75379a7b060Shersen wu 	if (smu_set_deep_sleep_dcefclk(smu, mhz))
75479a7b060Shersen wu 		return PP_SMU_RESULT_FAIL;
75579a7b060Shersen wu 
75679a7b060Shersen wu 	return PP_SMU_RESULT_OK;
75779a7b060Shersen wu }
75879a7b060Shersen wu 
75979a7b060Shersen wu enum pp_smu_status pp_nv_set_hard_min_dcefclk_by_freq(
76079a7b060Shersen wu 		struct pp_smu *pp, int mhz)
76179a7b060Shersen wu {
76279a7b060Shersen wu 	const struct dc_context *ctx = pp->dm;
76379a7b060Shersen wu 	struct amdgpu_device *adev = ctx->driver_context;
76479a7b060Shersen wu 	struct smu_context *smu = &adev->smu;
76579a7b060Shersen wu 	struct pp_display_clock_request clock_req;
76679a7b060Shersen wu 
76779a7b060Shersen wu 	if (!smu->funcs)
76879a7b060Shersen wu 		return PP_SMU_RESULT_UNSUPPORTED;
76979a7b060Shersen wu 
77079a7b060Shersen wu 	clock_req.clock_type = amd_pp_dcef_clock;
77179a7b060Shersen wu 	clock_req.clock_freq_in_khz = mhz * 1000;
77279a7b060Shersen wu 
77379a7b060Shersen wu 	/* 0: successful or smu.funcs->display_clock_voltage_request = NULL
77479a7b060Shersen wu 	 * 1: fail
77579a7b060Shersen wu 	 */
77679a7b060Shersen wu 	if (smu_display_clock_voltage_request(smu, &clock_req))
77779a7b060Shersen wu 		return PP_SMU_RESULT_FAIL;
77879a7b060Shersen wu 
77979a7b060Shersen wu 	return PP_SMU_RESULT_OK;
78079a7b060Shersen wu }
78179a7b060Shersen wu 
78279a7b060Shersen wu enum pp_smu_status pp_nv_set_hard_min_uclk_by_freq(struct pp_smu *pp, int mhz)
78379a7b060Shersen wu {
78479a7b060Shersen wu 	const struct dc_context *ctx = pp->dm;
78579a7b060Shersen wu 	struct amdgpu_device *adev = ctx->driver_context;
78679a7b060Shersen wu 	struct smu_context *smu = &adev->smu;
78779a7b060Shersen wu 	struct pp_display_clock_request clock_req;
78879a7b060Shersen wu 
78979a7b060Shersen wu 	if (!smu->funcs)
79079a7b060Shersen wu 		return PP_SMU_RESULT_UNSUPPORTED;
79179a7b060Shersen wu 
79279a7b060Shersen wu 	clock_req.clock_type = amd_pp_mem_clock;
79379a7b060Shersen wu 	clock_req.clock_freq_in_khz = mhz * 1000;
79479a7b060Shersen wu 
79579a7b060Shersen wu 	/* 0: successful or smu.funcs->display_clock_voltage_request = NULL
79679a7b060Shersen wu 	 * 1: fail
79779a7b060Shersen wu 	 */
79879a7b060Shersen wu 	if (smu_display_clock_voltage_request(smu, &clock_req))
79979a7b060Shersen wu 		return PP_SMU_RESULT_FAIL;
80079a7b060Shersen wu 
80179a7b060Shersen wu 	return PP_SMU_RESULT_OK;
80279a7b060Shersen wu }
80379a7b060Shersen wu 
80479a7b060Shersen wu enum pp_smu_status pp_nv_set_voltage_by_freq(struct pp_smu *pp,
80579a7b060Shersen wu 		enum pp_smu_nv_clock_id clock_id, int mhz)
80679a7b060Shersen wu {
80779a7b060Shersen wu 	const struct dc_context *ctx = pp->dm;
80879a7b060Shersen wu 	struct amdgpu_device *adev = ctx->driver_context;
80979a7b060Shersen wu 	struct smu_context *smu = &adev->smu;
81079a7b060Shersen wu 	struct pp_display_clock_request clock_req;
81179a7b060Shersen wu 
81279a7b060Shersen wu 	if (!smu->funcs)
81379a7b060Shersen wu 		return PP_SMU_RESULT_UNSUPPORTED;
81479a7b060Shersen wu 
81579a7b060Shersen wu 	switch (clock_id) {
81679a7b060Shersen wu 	case PP_SMU_NV_DISPCLK:
81779a7b060Shersen wu 		clock_req.clock_type = amd_pp_disp_clock;
81879a7b060Shersen wu 		break;
81979a7b060Shersen wu 	case PP_SMU_NV_PHYCLK:
82079a7b060Shersen wu 		clock_req.clock_type = amd_pp_phy_clock;
82179a7b060Shersen wu 		break;
82279a7b060Shersen wu 	case PP_SMU_NV_PIXELCLK:
82379a7b060Shersen wu 		clock_req.clock_type = amd_pp_pixel_clock;
82479a7b060Shersen wu 		break;
82579a7b060Shersen wu 	default:
82679a7b060Shersen wu 		break;
82779a7b060Shersen wu 	}
82879a7b060Shersen wu 	clock_req.clock_freq_in_khz = mhz * 1000;
82979a7b060Shersen wu 
83079a7b060Shersen wu 	/* 0: successful or smu.funcs->display_clock_voltage_request = NULL
83179a7b060Shersen wu 	 * 1: fail
83279a7b060Shersen wu 	 */
83379a7b060Shersen wu 	if (smu_display_clock_voltage_request(smu, &clock_req))
83479a7b060Shersen wu 		return PP_SMU_RESULT_FAIL;
83579a7b060Shersen wu 
83679a7b060Shersen wu 	return PP_SMU_RESULT_OK;
83779a7b060Shersen wu }
83879a7b060Shersen wu 
83979a7b060Shersen wu enum pp_smu_status pp_nv_get_maximum_sustainable_clocks(
84079a7b060Shersen wu 		struct pp_smu *pp, struct pp_smu_nv_clock_table *max_clocks)
84179a7b060Shersen wu {
84279a7b060Shersen wu 	const struct dc_context *ctx = pp->dm;
84379a7b060Shersen wu 	struct amdgpu_device *adev = ctx->driver_context;
84479a7b060Shersen wu 	struct smu_context *smu = &adev->smu;
84579a7b060Shersen wu 
84679a7b060Shersen wu 	if (!smu->funcs)
84779a7b060Shersen wu 		return PP_SMU_RESULT_UNSUPPORTED;
84879a7b060Shersen wu 
84979a7b060Shersen wu 	if (!smu->funcs->get_max_sustainable_clocks_by_dc)
85079a7b060Shersen wu 		return PP_SMU_RESULT_UNSUPPORTED;
85179a7b060Shersen wu 
85279a7b060Shersen wu 	if (!smu->funcs->get_max_sustainable_clocks_by_dc(smu, max_clocks))
85379a7b060Shersen wu 		return PP_SMU_RESULT_OK;
85479a7b060Shersen wu 
85579a7b060Shersen wu 	return PP_SMU_RESULT_FAIL;
85679a7b060Shersen wu }
85779a7b060Shersen wu 
85879a7b060Shersen wu enum pp_smu_status pp_nv_get_uclk_dpm_states(struct pp_smu *pp,
85979a7b060Shersen wu 		unsigned int *clock_values_in_khz, unsigned int *num_states)
86079a7b060Shersen wu {
86179a7b060Shersen wu 	const struct dc_context *ctx = pp->dm;
86279a7b060Shersen wu 	struct amdgpu_device *adev = ctx->driver_context;
86379a7b060Shersen wu 	struct smu_context *smu = &adev->smu;
86479a7b060Shersen wu 
86579a7b060Shersen wu 	if (!smu->ppt_funcs)
86679a7b060Shersen wu 		return PP_SMU_RESULT_UNSUPPORTED;
86779a7b060Shersen wu 
86879a7b060Shersen wu 	if (!smu->ppt_funcs->get_uclk_dpm_states)
86979a7b060Shersen wu 		return PP_SMU_RESULT_UNSUPPORTED;
87079a7b060Shersen wu 
87179a7b060Shersen wu 	if (!smu->ppt_funcs->get_uclk_dpm_states(smu,
87279a7b060Shersen wu 			clock_values_in_khz, num_states))
87379a7b060Shersen wu 		return PP_SMU_RESULT_OK;
87479a7b060Shersen wu 
87579a7b060Shersen wu 	return PP_SMU_RESULT_FAIL;
87679a7b060Shersen wu }
87779a7b060Shersen wu 
8780f1a6ad7SJun Lei void dm_pp_get_funcs(
879f7c1ed34SMikita Lipski 		struct dc_context *ctx,
8800f1a6ad7SJun Lei 		struct pp_smu_funcs *funcs)
881f7c1ed34SMikita Lipski {
88279a7b060Shersen wu 	switch (ctx->dce_version) {
88379a7b060Shersen wu 	case DCN_VERSION_1_0:
88479a7b060Shersen wu 	case DCN_VERSION_1_01:
88579a7b060Shersen wu 		funcs->ctx.ver = PP_SMU_VER_RV;
8860f1a6ad7SJun Lei 		funcs->rv_funcs.pp_smu.dm = ctx;
8870f1a6ad7SJun Lei 		funcs->rv_funcs.set_wm_ranges = pp_rv_set_wm_ranges;
8880f1a6ad7SJun Lei 		funcs->rv_funcs.set_pme_wa_enable = pp_rv_set_pme_wa_enable;
88979a7b060Shersen wu 		funcs->rv_funcs.set_display_count =
89079a7b060Shersen wu 				pp_rv_set_active_display_count;
89179a7b060Shersen wu 		funcs->rv_funcs.set_min_deep_sleep_dcfclk =
89279a7b060Shersen wu 				pp_rv_set_min_deep_sleep_dcfclk;
89379a7b060Shersen wu 		funcs->rv_funcs.set_hard_min_dcfclk_by_freq =
89479a7b060Shersen wu 				pp_rv_set_hard_min_dcefclk_by_freq;
89579a7b060Shersen wu 		funcs->rv_funcs.set_hard_min_fclk_by_freq =
89679a7b060Shersen wu 				pp_rv_set_hard_min_fclk_by_freq;
89779a7b060Shersen wu 		break;
89879a7b060Shersen wu #ifdef CONFIG_DRM_AMD_DC_DCN2_0
89979a7b060Shersen wu 	case DCN_VERSION_2_0:
90079a7b060Shersen wu 		funcs->ctx.ver = PP_SMU_VER_NV;
90179a7b060Shersen wu 		funcs->nv_funcs.pp_smu.dm = ctx;
90279a7b060Shersen wu 		funcs->nv_funcs.set_display_count = pp_nv_set_display_count;
90379a7b060Shersen wu 		funcs->nv_funcs.set_hard_min_dcfclk_by_freq =
90479a7b060Shersen wu 				pp_nv_set_hard_min_dcefclk_by_freq;
90579a7b060Shersen wu 		funcs->nv_funcs.set_min_deep_sleep_dcfclk =
90679a7b060Shersen wu 				pp_nv_set_min_deep_sleep_dcfclk;
90779a7b060Shersen wu 		funcs->nv_funcs.set_voltage_by_freq =
90879a7b060Shersen wu 				pp_nv_set_voltage_by_freq;
90979a7b060Shersen wu 		funcs->nv_funcs.set_wm_ranges = pp_nv_set_wm_ranges;
910588715bdShersen wu 
91179a7b060Shersen wu 		/* todo set_pme_wa_enable cause 4k@6ohz display not light up */
91279a7b060Shersen wu 		funcs->nv_funcs.set_pme_wa_enable = NULL;
91379a7b060Shersen wu 		/* todo debug waring message */
91479a7b060Shersen wu 		funcs->nv_funcs.set_hard_min_uclk_by_freq = NULL;
91579a7b060Shersen wu 		/* todo  compare data with window driver*/
91679a7b060Shersen wu 		funcs->nv_funcs.get_maximum_sustainable_clocks = NULL;
91779a7b060Shersen wu 		/*todo  compare data with window driver */
91879a7b060Shersen wu 		funcs->nv_funcs.get_uclk_dpm_states = NULL;
91979a7b060Shersen wu 		break;
92079a7b060Shersen wu #endif
92179a7b060Shersen wu 	default:
92279a7b060Shersen wu 		DRM_ERROR("smu version is not supported !\n");
92379a7b060Shersen wu 		break;
92479a7b060Shersen wu 	}
92579a7b060Shersen wu }
926