Blob Blame History Raw
From: Rex Zhu <Rex.Zhu@amd.com>
Date: Fri, 21 Apr 2017 14:02:10 +0800
Subject: drm/amd/powerplay: PP/DAL interface changes for dynamic clock switch
Git-commit: cd70f3d6e3fa816d516a22347292c4eda07cf8ee
Patch-mainline: v4.13-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c |  131 ++++++++++---------------
 1 file changed, 57 insertions(+), 74 deletions(-)

--- a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c
@@ -837,78 +837,54 @@ static uint32_t rv_get_mem_latency(struc
 		return MEM_LATENCY_ERR;
 }
 
-static void rv_get_memclocks(struct pp_hwmgr *hwmgr,
+static int rv_get_clock_by_type_with_latency(struct pp_hwmgr *hwmgr,
+		enum amd_pp_clock_type type,
 		struct pp_clock_levels_with_latency *clocks)
 {
-	struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend);
-	struct rv_clock_voltage_information *pinfo = &(rv_data->clock_vol_info);
-	struct rv_voltage_dependency_table *pmclk_table;
 	uint32_t i;
-
-	pmclk_table = pinfo->vdd_dep_on_mclk;
-	clocks->num_levels = 0;
-
-	for (i = 0; i < pmclk_table->count; i++) {
-		if (pmclk_table->entries[i].clk) {
-			clocks->data[clocks->num_levels].clocks_in_khz =
-						pmclk_table->entries[i].clk;
-			clocks->data[clocks->num_levels].latency_in_us =
-						rv_get_mem_latency(hwmgr,
-						pmclk_table->entries[i].clk);
-			clocks->num_levels++;
-		}
-	}
-}
-
-static void rv_get_dcefclocks(struct pp_hwmgr *hwmgr,
-		struct pp_clock_levels_with_latency *clocks)
-{
 	struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend);
 	struct rv_clock_voltage_information *pinfo = &(rv_data->clock_vol_info);
-	struct rv_voltage_dependency_table *pdcef_table;
-	uint32_t i;
-
-	pdcef_table = pinfo->vdd_dep_on_dcefclk;
-	for (i = 0; i < pdcef_table->count; i++) {
-		clocks->data[i].clocks_in_khz = pdcef_table->entries[i].clk;
-		clocks->data[i].latency_in_us = 0;
-	}
-	clocks->num_levels = pdcef_table->count;
-}
-
-static void rv_get_socclocks(struct pp_hwmgr *hwmgr,
-		struct pp_clock_levels_with_latency *clocks)
-{
-	struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend);
-	struct rv_clock_voltage_information *pinfo = &(rv_data->clock_vol_info);
-	struct rv_voltage_dependency_table *psoc_table;
-	uint32_t i;
-
-	psoc_table = pinfo->vdd_dep_on_socclk;
+	struct rv_voltage_dependency_table *pclk_vol_table;
+	bool latency_required = false;
 
-	for (i = 0; i < psoc_table->count; i++) {
-		clocks->data[i].clocks_in_khz = psoc_table->entries[i].clk;
-		clocks->data[i].latency_in_us = 0;
-	}
-	clocks->num_levels = psoc_table->count;
-}
+	if (pinfo == NULL)
+		return -EINVAL;
 
-static int rv_get_clock_by_type_with_latency(struct pp_hwmgr *hwmgr,
-		enum amd_pp_clock_type type,
-		struct pp_clock_levels_with_latency *clocks)
-{
 	switch (type) {
 	case amd_pp_mem_clock:
-		rv_get_memclocks(hwmgr, clocks);
+		pclk_vol_table = pinfo->vdd_dep_on_mclk;
+		latency_required = true;
 		break;
-	case amd_pp_dcef_clock:
-		rv_get_dcefclocks(hwmgr, clocks);
+	case amd_pp_f_clock:
+		pclk_vol_table = pinfo->vdd_dep_on_fclk;
+		latency_required = true;
 		break;
-	case amd_pp_soc_clock:
-		rv_get_socclocks(hwmgr, clocks);
+	case amd_pp_dcf_clock:
+		pclk_vol_table = pinfo->vdd_dep_on_dcefclk;
 		break;
+	case amd_pp_disp_clock:
+		pclk_vol_table = pinfo->vdd_dep_on_dispclk;
+		break;
+	case amd_pp_phy_clock:
+		pclk_vol_table = pinfo->vdd_dep_on_phyclk;
+		break;
+	case amd_pp_dpp_clock:
+		pclk_vol_table = pinfo->vdd_dep_on_dppclk;
 	default:
-		return -1;
+		return -EINVAL;
+	}
+
+	if (pclk_vol_table == NULL || pclk_vol_table->count == 0)
+		return -EINVAL;
+
+	clocks->num_levels = 0;
+	for (i = 0; i < pclk_vol_table->count; i++) {
+		clocks->data[i].clocks_in_khz = pclk_vol_table->entries[i].clk;
+		clocks->data[i].latency_in_us = latency_required ?
+						rv_get_mem_latency(hwmgr,
+						pclk_vol_table->entries[i].clk) :
+						0;
+		clocks->num_levels++;
 	}
 
 	return 0;
@@ -921,38 +897,38 @@ static int rv_get_clock_by_type_with_vol
 	uint32_t i;
 	struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend);
 	struct rv_clock_voltage_information *pinfo = &(rv_data->clock_vol_info);
-	struct rv_voltage_dependency_table *pclk_vol_table;
+	struct rv_voltage_dependency_table *pclk_vol_table = NULL;
+
+	if (pinfo == NULL)
+		return -EINVAL;
 
 	switch (type) {
 	case amd_pp_mem_clock:
 		pclk_vol_table = pinfo->vdd_dep_on_mclk;
 		break;
-	case amd_pp_dcef_clock:
-		pclk_vol_table = pinfo->vdd_dep_on_dcefclk;
+	case amd_pp_f_clock:
+		pclk_vol_table = pinfo->vdd_dep_on_fclk;
 		break;
-	case amd_pp_disp_clock:
-		pclk_vol_table = pinfo->vdd_dep_on_dispclk;
+	case amd_pp_dcf_clock:
+		pclk_vol_table = pinfo->vdd_dep_on_dcefclk;
 		break;
-	case amd_pp_phy_clock:
-		pclk_vol_table = pinfo->vdd_dep_on_phyclk;
+	case amd_pp_soc_clock:
+		pclk_vol_table = pinfo->vdd_dep_on_socclk;
 		break;
-	case amd_pp_dpp_clock:
-		pclk_vol_table = pinfo->vdd_dep_on_dppclk;
 	default:
 		return -EINVAL;
 	}
 
-	if (pclk_vol_table->count == 0)
+	if (pclk_vol_table == NULL || pclk_vol_table->count == 0)
 		return -EINVAL;
 
+	clocks->num_levels = 0;
 	for (i = 0; i < pclk_vol_table->count; i++) {
 		clocks->data[i].clocks_in_khz = pclk_vol_table->entries[i].clk;
 		clocks->data[i].voltage_in_mv = pclk_vol_table->entries[i].vol;
 		clocks->num_levels++;
 	}
 
-	clocks->num_levels = pclk_vol_table->count;
-
 	return 0;
 }
 
@@ -960,18 +936,25 @@ int rv_display_clock_voltage_request(str
 		struct pp_display_clock_request *clock_req)
 {
 	int result = 0;
+	struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend);
 	enum amd_pp_clock_type clk_type = clock_req->clock_type;
-	uint32_t clk_freq = clock_req->clock_freq_in_khz / 100;
+	uint32_t clk_freq = clock_req->clock_freq_in_khz / 1000;
 	PPSMC_Msg        msg;
 
 	switch (clk_type) {
-	case amd_pp_dcef_clock:
+	case amd_pp_dcf_clock:
+		if (clk_freq == rv_data->dcf_actual_hard_min_freq)
+			return 0;
 		msg =  PPSMC_MSG_SetHardMinDcefclkByFreq;
+		rv_data->dcf_actual_hard_min_freq = clk_freq;
 		break;
 	case amd_pp_soc_clock:
 		 msg = PPSMC_MSG_SetHardMinSocclkByFreq;
 		break;
-	case amd_pp_mem_clock:
+	case amd_pp_f_clock:
+		if (clk_freq == rv_data->f_actual_hard_min_freq)
+			return 0;
+		rv_data->f_actual_hard_min_freq = clk_freq;
 		msg = PPSMC_MSG_SetHardMinFclkByFreq;
 		break;
 	default: