From 1543e317f1da31b75942316931e8f491a8920811 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Thu, 04 Jan 2024 10:08:02 +0000
Subject: [PATCH] disable FB

---
 kernel/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c |  504 ++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 436 insertions(+), 68 deletions(-)

diff --git a/kernel/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c b/kernel/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
index 4ba0003..6e575ff 100644
--- a/kernel/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
+++ b/kernel/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
@@ -24,8 +24,7 @@
 #include <linux/string.h>
 #include <linux/acpi.h>
 
-#include <drm/drmP.h>
-#include <drm/drm_crtc_helper.h>
+#include <drm/drm_probe_helper.h>
 #include <drm/amdgpu_drm.h>
 #include "dm_services.h"
 #include "amdgpu.h"
@@ -33,6 +32,7 @@
 #include "amdgpu_dm_irq.h"
 #include "amdgpu_pm.h"
 #include "dm_pp_smu.h"
+#include "amdgpu_smu.h"
 
 
 bool dm_pp_apply_display_requirements(
@@ -40,6 +40,7 @@
 		const struct dm_pp_display_configuration *pp_display_cfg)
 {
 	struct amdgpu_device *adev = ctx->driver_context;
+	struct smu_context *smu = &adev->smu;
 	int i;
 
 	if (adev->pm.dpm_enabled) {
@@ -101,17 +102,14 @@
 			adev->pm.pm_display_cfg.displays[i].controller_id = dc_cfg->pipe_idx + 1;
 		}
 
-		/* TODO: complete implementation of
-		 * pp_display_configuration_change().
-		 * Follow example of:
-		 * PHM_StoreDALConfigurationData - powerplay\hwmgr\hardwaremanager.c
-		 * PP_IRI_DisplayConfigurationChange - powerplay\eventmgr\iri.c */
-		if (adev->powerplay.pp_funcs->display_configuration_change)
+		if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->display_configuration_change)
 			adev->powerplay.pp_funcs->display_configuration_change(
 				adev->powerplay.pp_handle,
 				&adev->pm.pm_display_cfg);
+		else if (adev->smu.ppt_funcs)
+			smu_display_configuration_change(smu,
+							 &adev->pm.pm_display_cfg);
 
-		/* TODO: replace by a separate call to 'apply display cfg'? */
 		amdgpu_pm_compute_clocks(adev);
 	}
 
@@ -148,6 +146,36 @@
 		clks->num_levels = 0;
 		break;
 	}
+}
+
+static enum smu_clk_type dc_to_smu_clock_type(
+		enum dm_pp_clock_type dm_pp_clk_type)
+{
+	enum smu_clk_type smu_clk_type = SMU_CLK_COUNT;
+
+	switch (dm_pp_clk_type) {
+	case DM_PP_CLOCK_TYPE_DISPLAY_CLK:
+		smu_clk_type = SMU_DISPCLK;
+		break;
+	case DM_PP_CLOCK_TYPE_ENGINE_CLK:
+		smu_clk_type = SMU_GFXCLK;
+		break;
+	case DM_PP_CLOCK_TYPE_MEMORY_CLK:
+		smu_clk_type = SMU_MCLK;
+		break;
+	case DM_PP_CLOCK_TYPE_DCEFCLK:
+		smu_clk_type = SMU_DCEFCLK;
+		break;
+	case DM_PP_CLOCK_TYPE_SOCCLK:
+		smu_clk_type = SMU_SOCCLK;
+		break;
+	default:
+		DRM_ERROR("DM_PPLIB: invalid clock type: %d!\n",
+			  dm_pp_clk_type);
+		break;
+	}
+
+	return smu_clk_type;
 }
 
 static enum amd_pp_clock_type dc_to_pp_clock_type(
@@ -293,7 +321,8 @@
 			DC_DECODE_PP_CLOCK_TYPE(dc_clk_type));
 
 	for (i = 0; i < clk_level_info->num_levels; i++) {
-		DRM_INFO("DM_PPLIB:\t %d in kHz\n", pp_clks->data[i].clocks_in_khz);
+		DRM_INFO("DM_PPLIB:\t %d in kHz, %d in mV\n", pp_clks->data[i].clocks_in_khz,
+			 pp_clks->data[i].voltage_in_mv);
 		clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz;
 		clk_level_info->data[i].voltage_in_mv = pp_clks->data[i].voltage_in_mv;
 	}
@@ -310,10 +339,17 @@
 	struct amd_pp_simple_clock_info validation_clks = { 0 };
 	uint32_t i;
 
-	if (adev->powerplay.pp_funcs->get_clock_by_type) {
+	if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_clock_by_type) {
 		if (adev->powerplay.pp_funcs->get_clock_by_type(pp_handle,
 			dc_to_pp_clock_type(clk_type), &pp_clks)) {
-		/* Error in pplib. Provide default values. */
+			/* Error in pplib. Provide default values. */
+			get_default_clock_levels(clk_type, dc_clks);
+			return true;
+		}
+	} else if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->get_clock_by_type) {
+		if (smu_get_clock_by_type(&adev->smu,
+					  dc_to_pp_clock_type(clk_type),
+					  &pp_clks)) {
 			get_default_clock_levels(clk_type, dc_clks);
 			return true;
 		}
@@ -321,10 +357,17 @@
 
 	pp_to_dc_clock_levels(&pp_clks, dc_clks, clk_type);
 
-	if (adev->powerplay.pp_funcs->get_display_mode_validation_clocks) {
+	if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_display_mode_validation_clocks) {
 		if (adev->powerplay.pp_funcs->get_display_mode_validation_clocks(
 						pp_handle, &validation_clks)) {
 			/* Error in pplib. Provide default values. */
+			DRM_INFO("DM_PPLIB: Warning: using default validation clocks!\n");
+			validation_clks.engine_max_clock = 72000;
+			validation_clks.memory_max_clock = 80000;
+			validation_clks.level = 0;
+		}
+	} else if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->get_max_high_clocks) {
+		if (smu_get_max_high_clocks(&adev->smu, &validation_clks)) {
 			DRM_INFO("DM_PPLIB: Warning: using default validation clocks!\n");
 			validation_clks.engine_max_clock = 72000;
 			validation_clks.memory_max_clock = 80000;
@@ -380,14 +423,21 @@
 	void *pp_handle = adev->powerplay.pp_handle;
 	struct pp_clock_levels_with_latency pp_clks = { 0 };
 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
+	int ret;
 
-	if (!pp_funcs || !pp_funcs->get_clock_by_type_with_latency)
-		return false;
+	if (pp_funcs && pp_funcs->get_clock_by_type_with_latency) {
+		ret = pp_funcs->get_clock_by_type_with_latency(pp_handle,
+						dc_to_pp_clock_type(clk_type),
+						&pp_clks);
+		if (ret)
+			return false;
+	} else if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->get_clock_by_type_with_latency) {
+		if (smu_get_clock_by_type_with_latency(&adev->smu,
+						       dc_to_smu_clock_type(clk_type),
+						       &pp_clks))
+			return false;
+	}
 
-	if (pp_funcs->get_clock_by_type_with_latency(pp_handle,
-						     dc_to_pp_clock_type(clk_type),
-						     &pp_clks))
-		return false;
 
 	pp_to_dc_clock_levels_with_latency(&pp_clks, clk_level_info, clk_type);
 
@@ -403,11 +453,20 @@
 	void *pp_handle = adev->powerplay.pp_handle;
 	struct pp_clock_levels_with_voltage pp_clk_info = {0};
 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
+	int ret;
 
-	if (pp_funcs->get_clock_by_type_with_voltage(pp_handle,
-						     dc_to_pp_clock_type(clk_type),
-						     &pp_clk_info))
-		return false;
+	if (pp_funcs && pp_funcs->get_clock_by_type_with_voltage) {
+		ret = pp_funcs->get_clock_by_type_with_voltage(pp_handle,
+						dc_to_pp_clock_type(clk_type),
+						&pp_clk_info);
+		if (ret)
+			return false;
+	} else if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->get_clock_by_type_with_voltage) {
+		if (smu_get_clock_by_type_with_voltage(&adev->smu,
+						       dc_to_pp_clock_type(clk_type),
+						       &pp_clk_info))
+			return false;
+	}
 
 	pp_to_dc_clock_levels_with_voltage(&pp_clk_info, clk_level_info, clk_type);
 
@@ -444,10 +503,14 @@
 	if (!pp_clock_request.clock_type)
 		return false;
 
-	if (adev->powerplay.pp_funcs->display_clock_voltage_request)
+	if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->display_clock_voltage_request)
 		ret = adev->powerplay.pp_funcs->display_clock_voltage_request(
 			adev->powerplay.pp_handle,
 			&pp_clock_request);
+	else if (adev->smu.ppt_funcs &&
+		 adev->smu.ppt_funcs->display_clock_voltage_request)
+		ret = smu_display_clock_voltage_request(&adev->smu,
+							&pp_clock_request);
 	if (ret)
 		return false;
 	return true;
@@ -461,10 +524,14 @@
 	struct amd_pp_clock_info pp_clk_info = {0};
 	int ret = 0;
 
-	if (adev->powerplay.pp_funcs->get_current_clocks)
+	if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_current_clocks)
 		ret = adev->powerplay.pp_funcs->get_current_clocks(
 			adev->powerplay.pp_handle,
 			&pp_clk_info);
+	else if (adev->smu.ppt_funcs)
+		ret = smu_get_current_clocks(&adev->smu, &pp_clk_info);
+	else
+		return false;
 	if (ret)
 		return false;
 
@@ -475,31 +542,10 @@
 	return true;
 }
 
-void pp_rv_set_display_requirement(struct pp_smu *pp,
-		struct pp_smu_display_requirement_rv *req)
-{
-	struct dc_context *ctx = pp->ctx;
-	struct amdgpu_device *adev = ctx->driver_context;
-	void *pp_handle = adev->powerplay.pp_handle;
-	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
-	struct pp_display_clock_request clock = {0};
-
-	if (!pp_funcs || !pp_funcs->display_clock_voltage_request)
-		return;
-
-	clock.clock_type = amd_pp_dcf_clock;
-	clock.clock_freq_in_khz = req->hard_min_dcefclk_khz;
-	pp_funcs->display_clock_voltage_request(pp_handle, &clock);
-
-	clock.clock_type = amd_pp_f_clock;
-	clock.clock_freq_in_khz = req->hard_min_fclk_khz;
-	pp_funcs->display_clock_voltage_request(pp_handle, &clock);
-}
-
 void pp_rv_set_wm_ranges(struct pp_smu *pp,
 		struct pp_smu_wm_range_sets *ranges)
 {
-	struct dc_context *ctx = pp->ctx;
+	const struct dc_context *ctx = pp->dm;
 	struct amdgpu_device *adev = ctx->driver_context;
 	void *pp_handle = adev->powerplay.pp_handle;
 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
@@ -518,13 +564,13 @@
 			wm_dce_clocks[i].wm_set_id =
 					ranges->reader_wm_sets[i].wm_inst;
 		wm_dce_clocks[i].wm_max_dcfclk_clk_in_khz =
-				ranges->reader_wm_sets[i].max_drain_clk_khz;
+				ranges->reader_wm_sets[i].max_drain_clk_mhz * 1000;
 		wm_dce_clocks[i].wm_min_dcfclk_clk_in_khz =
-				ranges->reader_wm_sets[i].min_drain_clk_khz;
+				ranges->reader_wm_sets[i].min_drain_clk_mhz * 1000;
 		wm_dce_clocks[i].wm_max_mem_clk_in_khz =
-				ranges->reader_wm_sets[i].max_fill_clk_khz;
+				ranges->reader_wm_sets[i].max_fill_clk_mhz * 1000;
 		wm_dce_clocks[i].wm_min_mem_clk_in_khz =
-				ranges->reader_wm_sets[i].min_fill_clk_khz;
+				ranges->reader_wm_sets[i].min_fill_clk_mhz * 1000;
 	}
 
 	for (i = 0; i < wm_with_clock_ranges.num_wm_mcif_sets; i++) {
@@ -534,37 +580,359 @@
 			wm_soc_clocks[i].wm_set_id =
 					ranges->writer_wm_sets[i].wm_inst;
 		wm_soc_clocks[i].wm_max_socclk_clk_in_khz =
-				ranges->writer_wm_sets[i].max_fill_clk_khz;
+				ranges->writer_wm_sets[i].max_fill_clk_mhz * 1000;
 		wm_soc_clocks[i].wm_min_socclk_clk_in_khz =
-				ranges->writer_wm_sets[i].min_fill_clk_khz;
+				ranges->writer_wm_sets[i].min_fill_clk_mhz * 1000;
 		wm_soc_clocks[i].wm_max_mem_clk_in_khz =
-				ranges->writer_wm_sets[i].max_drain_clk_khz;
+				ranges->writer_wm_sets[i].max_drain_clk_mhz * 1000;
 		wm_soc_clocks[i].wm_min_mem_clk_in_khz =
-				ranges->writer_wm_sets[i].min_drain_clk_khz;
+				ranges->writer_wm_sets[i].min_drain_clk_mhz * 1000;
 	}
 
-	pp_funcs->set_watermarks_for_clocks_ranges(pp_handle, &wm_with_clock_ranges);
+	if (pp_funcs && pp_funcs->set_watermarks_for_clocks_ranges)
+		pp_funcs->set_watermarks_for_clocks_ranges(pp_handle,
+							   &wm_with_clock_ranges);
 }
 
 void pp_rv_set_pme_wa_enable(struct pp_smu *pp)
 {
-	struct dc_context *ctx = pp->ctx;
+	const struct dc_context *ctx = pp->dm;
 	struct amdgpu_device *adev = ctx->driver_context;
 	void *pp_handle = adev->powerplay.pp_handle;
 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
 
-	if (!pp_funcs || !pp_funcs->notify_smu_enable_pwe)
-		return;
-
-	pp_funcs->notify_smu_enable_pwe(pp_handle);
+	if (pp_funcs && pp_funcs->notify_smu_enable_pwe)
+		pp_funcs->notify_smu_enable_pwe(pp_handle);
+	else if (adev->smu.ppt_funcs)
+		smu_notify_smu_enable_pwe(&adev->smu);
 }
 
-void dm_pp_get_funcs_rv(
-		struct dc_context *ctx,
-		struct pp_smu_funcs_rv *funcs)
+void pp_rv_set_active_display_count(struct pp_smu *pp, int count)
 {
-	funcs->pp_smu.ctx = ctx;
-	funcs->set_display_requirement = pp_rv_set_display_requirement;
-	funcs->set_wm_ranges = pp_rv_set_wm_ranges;
-	funcs->set_pme_wa_enable = pp_rv_set_pme_wa_enable;
+	const struct dc_context *ctx = pp->dm;
+	struct amdgpu_device *adev = ctx->driver_context;
+	void *pp_handle = adev->powerplay.pp_handle;
+	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
+
+	if (!pp_funcs || !pp_funcs->set_active_display_count)
+		return;
+
+	pp_funcs->set_active_display_count(pp_handle, count);
+}
+
+void pp_rv_set_min_deep_sleep_dcfclk(struct pp_smu *pp, int clock)
+{
+	const struct dc_context *ctx = pp->dm;
+	struct amdgpu_device *adev = ctx->driver_context;
+	void *pp_handle = adev->powerplay.pp_handle;
+	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
+
+	if (!pp_funcs || !pp_funcs->set_min_deep_sleep_dcefclk)
+		return;
+
+	pp_funcs->set_min_deep_sleep_dcefclk(pp_handle, clock);
+}
+
+void pp_rv_set_hard_min_dcefclk_by_freq(struct pp_smu *pp, int clock)
+{
+	const struct dc_context *ctx = pp->dm;
+	struct amdgpu_device *adev = ctx->driver_context;
+	void *pp_handle = adev->powerplay.pp_handle;
+	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
+
+	if (!pp_funcs || !pp_funcs->set_hard_min_dcefclk_by_freq)
+		return;
+
+	pp_funcs->set_hard_min_dcefclk_by_freq(pp_handle, clock);
+}
+
+void pp_rv_set_hard_min_fclk_by_freq(struct pp_smu *pp, int mhz)
+{
+	const struct dc_context *ctx = pp->dm;
+	struct amdgpu_device *adev = ctx->driver_context;
+	void *pp_handle = adev->powerplay.pp_handle;
+	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
+
+	if (!pp_funcs || !pp_funcs->set_hard_min_fclk_by_freq)
+		return;
+
+	pp_funcs->set_hard_min_fclk_by_freq(pp_handle, mhz);
+}
+
+static enum pp_smu_status pp_nv_set_wm_ranges(struct pp_smu *pp,
+		struct pp_smu_wm_range_sets *ranges)
+{
+	const struct dc_context *ctx = pp->dm;
+	struct amdgpu_device *adev = ctx->driver_context;
+
+	smu_set_watermarks_for_clock_ranges(&adev->smu, ranges);
+
+	return PP_SMU_RESULT_OK;
+}
+
+enum pp_smu_status pp_nv_set_pme_wa_enable(struct pp_smu *pp)
+{
+	const struct dc_context *ctx = pp->dm;
+	struct amdgpu_device *adev = ctx->driver_context;
+	struct smu_context *smu = &adev->smu;
+
+	if (!smu->ppt_funcs)
+		return PP_SMU_RESULT_UNSUPPORTED;
+
+	/* 0: successful or smu.ppt_funcs->set_azalia_d3_pme = NULL;  1: fail */
+	if (smu_set_azalia_d3_pme(smu))
+		return PP_SMU_RESULT_FAIL;
+
+	return PP_SMU_RESULT_OK;
+}
+
+static enum pp_smu_status pp_nv_set_display_count(struct pp_smu *pp, int count)
+{
+	const struct dc_context *ctx = pp->dm;
+	struct amdgpu_device *adev = ctx->driver_context;
+	struct smu_context *smu = &adev->smu;
+
+	if (!smu->ppt_funcs)
+		return PP_SMU_RESULT_UNSUPPORTED;
+
+	/* 0: successful or smu.ppt_funcs->set_display_count = NULL;  1: fail */
+	if (smu_set_display_count(smu, count))
+		return PP_SMU_RESULT_FAIL;
+
+	return PP_SMU_RESULT_OK;
+}
+
+static enum pp_smu_status
+pp_nv_set_min_deep_sleep_dcfclk(struct pp_smu *pp, int mhz)
+{
+	const struct dc_context *ctx = pp->dm;
+	struct amdgpu_device *adev = ctx->driver_context;
+	struct smu_context *smu = &adev->smu;
+
+	if (!smu->ppt_funcs)
+		return PP_SMU_RESULT_UNSUPPORTED;
+
+	/* 0: successful or smu.ppt_funcs->set_deep_sleep_dcefclk = NULL;1: fail */
+	if (smu_set_deep_sleep_dcefclk(smu, mhz))
+		return PP_SMU_RESULT_FAIL;
+
+	return PP_SMU_RESULT_OK;
+}
+
+static enum pp_smu_status pp_nv_set_hard_min_dcefclk_by_freq(
+		struct pp_smu *pp, int mhz)
+{
+	const struct dc_context *ctx = pp->dm;
+	struct amdgpu_device *adev = ctx->driver_context;
+	struct smu_context *smu = &adev->smu;
+	struct pp_display_clock_request clock_req;
+
+	if (!smu->ppt_funcs)
+		return PP_SMU_RESULT_UNSUPPORTED;
+
+	clock_req.clock_type = amd_pp_dcef_clock;
+	clock_req.clock_freq_in_khz = mhz * 1000;
+
+	/* 0: successful or smu.ppt_funcs->display_clock_voltage_request = NULL
+	 * 1: fail
+	 */
+	if (smu_display_clock_voltage_request(smu, &clock_req))
+		return PP_SMU_RESULT_FAIL;
+
+	return PP_SMU_RESULT_OK;
+}
+
+static enum pp_smu_status
+pp_nv_set_hard_min_uclk_by_freq(struct pp_smu *pp, int mhz)
+{
+	const struct dc_context *ctx = pp->dm;
+	struct amdgpu_device *adev = ctx->driver_context;
+	struct smu_context *smu = &adev->smu;
+	struct pp_display_clock_request clock_req;
+
+	if (!smu->ppt_funcs)
+		return PP_SMU_RESULT_UNSUPPORTED;
+
+	clock_req.clock_type = amd_pp_mem_clock;
+	clock_req.clock_freq_in_khz = mhz * 1000;
+
+	/* 0: successful or smu.ppt_funcs->display_clock_voltage_request = NULL
+	 * 1: fail
+	 */
+	if (smu_display_clock_voltage_request(smu, &clock_req))
+		return PP_SMU_RESULT_FAIL;
+
+	return PP_SMU_RESULT_OK;
+}
+
+static enum pp_smu_status pp_nv_set_pstate_handshake_support(
+	struct pp_smu *pp, bool pstate_handshake_supported)
+{
+	const struct dc_context *ctx = pp->dm;
+	struct amdgpu_device *adev = ctx->driver_context;
+	struct smu_context *smu = &adev->smu;
+
+	if (smu_display_disable_memory_clock_switch(smu, !pstate_handshake_supported))
+		return PP_SMU_RESULT_FAIL;
+
+	return PP_SMU_RESULT_OK;
+}
+
+static enum pp_smu_status pp_nv_set_voltage_by_freq(struct pp_smu *pp,
+		enum pp_smu_nv_clock_id clock_id, int mhz)
+{
+	const struct dc_context *ctx = pp->dm;
+	struct amdgpu_device *adev = ctx->driver_context;
+	struct smu_context *smu = &adev->smu;
+	struct pp_display_clock_request clock_req;
+
+	if (!smu->ppt_funcs)
+		return PP_SMU_RESULT_UNSUPPORTED;
+
+	switch (clock_id) {
+	case PP_SMU_NV_DISPCLK:
+		clock_req.clock_type = amd_pp_disp_clock;
+		break;
+	case PP_SMU_NV_PHYCLK:
+		clock_req.clock_type = amd_pp_phy_clock;
+		break;
+	case PP_SMU_NV_PIXELCLK:
+		clock_req.clock_type = amd_pp_pixel_clock;
+		break;
+	default:
+		break;
+	}
+	clock_req.clock_freq_in_khz = mhz * 1000;
+
+	/* 0: successful or smu.ppt_funcs->display_clock_voltage_request = NULL
+	 * 1: fail
+	 */
+	if (smu_display_clock_voltage_request(smu, &clock_req))
+		return PP_SMU_RESULT_FAIL;
+
+	return PP_SMU_RESULT_OK;
+}
+
+static enum pp_smu_status pp_nv_get_maximum_sustainable_clocks(
+		struct pp_smu *pp, struct pp_smu_nv_clock_table *max_clocks)
+{
+	const struct dc_context *ctx = pp->dm;
+	struct amdgpu_device *adev = ctx->driver_context;
+	struct smu_context *smu = &adev->smu;
+
+	if (!smu->ppt_funcs)
+		return PP_SMU_RESULT_UNSUPPORTED;
+
+	if (!smu->ppt_funcs->get_max_sustainable_clocks_by_dc)
+		return PP_SMU_RESULT_UNSUPPORTED;
+
+	if (!smu_get_max_sustainable_clocks_by_dc(smu, max_clocks))
+		return PP_SMU_RESULT_OK;
+
+	return PP_SMU_RESULT_FAIL;
+}
+
+static enum pp_smu_status pp_nv_get_uclk_dpm_states(struct pp_smu *pp,
+		unsigned int *clock_values_in_khz, unsigned int *num_states)
+{
+	const struct dc_context *ctx = pp->dm;
+	struct amdgpu_device *adev = ctx->driver_context;
+	struct smu_context *smu = &adev->smu;
+
+	if (!smu->ppt_funcs)
+		return PP_SMU_RESULT_UNSUPPORTED;
+
+	if (!smu->ppt_funcs->get_uclk_dpm_states)
+		return PP_SMU_RESULT_UNSUPPORTED;
+
+	if (!smu_get_uclk_dpm_states(smu,
+			clock_values_in_khz, num_states))
+		return PP_SMU_RESULT_OK;
+
+	return PP_SMU_RESULT_FAIL;
+}
+
+static enum pp_smu_status pp_rn_get_dpm_clock_table(
+		struct pp_smu *pp, struct dpm_clocks *clock_table)
+{
+	const struct dc_context *ctx = pp->dm;
+	struct amdgpu_device *adev = ctx->driver_context;
+	struct smu_context *smu = &adev->smu;
+
+	if (!smu->ppt_funcs)
+		return PP_SMU_RESULT_UNSUPPORTED;
+
+	if (!smu->ppt_funcs->get_dpm_clock_table)
+		return PP_SMU_RESULT_UNSUPPORTED;
+
+	if (!smu_get_dpm_clock_table(smu, clock_table))
+		return PP_SMU_RESULT_OK;
+
+	return PP_SMU_RESULT_FAIL;
+}
+
+static enum pp_smu_status pp_rn_set_wm_ranges(struct pp_smu *pp,
+		struct pp_smu_wm_range_sets *ranges)
+{
+	const struct dc_context *ctx = pp->dm;
+	struct amdgpu_device *adev = ctx->driver_context;
+
+	smu_set_watermarks_for_clock_ranges(&adev->smu, ranges);
+
+	return PP_SMU_RESULT_OK;
+}
+
+void dm_pp_get_funcs(
+		struct dc_context *ctx,
+		struct pp_smu_funcs *funcs)
+{
+	switch (ctx->dce_version) {
+	case DCN_VERSION_1_0:
+	case DCN_VERSION_1_01:
+		funcs->ctx.ver = PP_SMU_VER_RV;
+		funcs->rv_funcs.pp_smu.dm = ctx;
+		funcs->rv_funcs.set_wm_ranges = pp_rv_set_wm_ranges;
+		funcs->rv_funcs.set_pme_wa_enable = pp_rv_set_pme_wa_enable;
+		funcs->rv_funcs.set_display_count =
+				pp_rv_set_active_display_count;
+		funcs->rv_funcs.set_min_deep_sleep_dcfclk =
+				pp_rv_set_min_deep_sleep_dcfclk;
+		funcs->rv_funcs.set_hard_min_dcfclk_by_freq =
+				pp_rv_set_hard_min_dcefclk_by_freq;
+		funcs->rv_funcs.set_hard_min_fclk_by_freq =
+				pp_rv_set_hard_min_fclk_by_freq;
+		break;
+	case DCN_VERSION_2_0:
+		funcs->ctx.ver = PP_SMU_VER_NV;
+		funcs->nv_funcs.pp_smu.dm = ctx;
+		funcs->nv_funcs.set_display_count = pp_nv_set_display_count;
+		funcs->nv_funcs.set_hard_min_dcfclk_by_freq =
+				pp_nv_set_hard_min_dcefclk_by_freq;
+		funcs->nv_funcs.set_min_deep_sleep_dcfclk =
+				pp_nv_set_min_deep_sleep_dcfclk;
+		funcs->nv_funcs.set_voltage_by_freq =
+				pp_nv_set_voltage_by_freq;
+		funcs->nv_funcs.set_wm_ranges = pp_nv_set_wm_ranges;
+
+		/* todo set_pme_wa_enable cause 4k@6ohz display not light up */
+		funcs->nv_funcs.set_pme_wa_enable = NULL;
+		/* todo debug waring message */
+		funcs->nv_funcs.set_hard_min_uclk_by_freq = pp_nv_set_hard_min_uclk_by_freq;
+		/* todo  compare data with window driver*/
+		funcs->nv_funcs.get_maximum_sustainable_clocks = pp_nv_get_maximum_sustainable_clocks;
+		/*todo  compare data with window driver */
+		funcs->nv_funcs.get_uclk_dpm_states = pp_nv_get_uclk_dpm_states;
+		funcs->nv_funcs.set_pstate_handshake_support = pp_nv_set_pstate_handshake_support;
+		break;
+
+	case DCN_VERSION_2_1:
+		funcs->ctx.ver = PP_SMU_VER_RN;
+		funcs->rn_funcs.pp_smu.dm = ctx;
+		funcs->rn_funcs.set_wm_ranges = pp_rn_set_wm_ranges;
+		funcs->rn_funcs.get_dpm_clock_table = pp_rn_get_dpm_clock_table;
+		break;
+	default:
+		DRM_ERROR("smu version is not supported !\n");
+		break;
+	}
 }

--
Gitblit v1.6.2