[PATCH 273/459] drm/amd/powerplay: add thermal ctf support for navi10

Alex Deucher alexdeucher at gmail.com
Mon Jun 17 19:30:40 UTC 2019


From: Kevin Wang <kevin1.wang at amd.com>

add sw-CTF support for navi10

Signed-off-by: Kevin Wang <kevin1.wang at amd.com>
Reviewed-by: Huang Rui <ray.huang at amd.com>
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
---
 drivers/gpu/drm/amd/powerplay/amdgpu_smu.c    |  7 ++
 .../gpu/drm/amd/powerplay/inc/amdgpu_smu.h    |  4 +
 drivers/gpu/drm/amd/powerplay/navi10_ppt.c    |  2 +
 drivers/gpu/drm/amd/powerplay/smu_v11_0.c     | 78 +++++++++++++++++++
 4 files changed, 91 insertions(+)

diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
index bca863e80398..421e1df79ae5 100644
--- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
+++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
@@ -1007,6 +1007,10 @@ static int smu_hw_init(void *handle)
 	if (ret)
 		goto failed;
 
+	ret = smu_register_irq_handler(smu);
+	if (ret)
+		goto failed;
+
 	mutex_unlock(&smu->mutex);
 
 	if (!smu->pm_enabled)
@@ -1051,6 +1055,9 @@ static int smu_hw_fini(void *handle)
 	kfree(table_context->od8_settings);
 	table_context->od8_settings = NULL;
 
+	kfree(smu->irq_source);
+	smu->irq_source = NULL;
+
 	ret = smu_fini_fb_allocations(smu);
 	if (ret)
 		return ret;
diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
index f89971992e6f..5e49b38ddd0d 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
@@ -497,6 +497,7 @@ struct mclock_latency_table {
 struct smu_context
 {
 	struct amdgpu_device            *adev;
+	struct amdgpu_irq_src		*irq_source;
 
 	const struct smu_funcs		*funcs;
 	const struct pptable_funcs	*ppt_funcs;
@@ -687,6 +688,7 @@ struct smu_funcs
 	int (*set_fan_speed_rpm)(struct smu_context *smu, uint32_t speed);
 	int (*set_xgmi_pstate)(struct smu_context *smu, uint32_t pstate);
 	int (*gfx_off_control)(struct smu_context *smu, bool enable);
+	int (*register_irq_handler)(struct smu_context *smu);
 };
 
 #define smu_init_microcode(smu) \
@@ -895,6 +897,8 @@ struct smu_funcs
 	((smu)->ppt_funcs->get_current_clk_freq_by_table ? (smu)->ppt_funcs->get_current_clk_freq_by_table((smu), (clk_type), (value)) : 0)
 #define smu_get_thermal_temperature_range(smu, range) \
 	((smu)->ppt_funcs->get_thermal_temperature_range? (smu)->ppt_funcs->get_thermal_temperature_range((smu), (range)) : 0)
+#define smu_register_irq_handler(smu) \
+	((smu)->funcs->register_irq_handler ? (smu)->funcs->register_irq_handler(smu) : 0)
 
 extern int smu_get_atom_data_table(struct smu_context *smu, uint32_t table,
 				   uint16_t *size, uint8_t *frev, uint8_t *crev,
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index f5fb672bddc2..d130d491aa85 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -476,6 +476,8 @@ static int navi10_store_powerplay_table(struct smu_context *smu)
 	memcpy(table_context->driver_pptable, &powerplay_table->smc_pptable,
 	       sizeof(PPTable_t));
 
+	table_context->thermal_controller_type = powerplay_table->thermal_controller_type;
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
index c6dc2a6d8093..57a50a9162e9 100644
--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
+++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
@@ -1131,6 +1131,8 @@ static int smu_v11_0_set_thermal_range(struct smu_context *smu,
 	val = RREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL);
 	val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5);
 	val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1);
+	val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_INTH_MASK, 0);
+	val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_INTL_MASK, 0);
 	val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high / SMU_TEMPERATURE_UNITS_PER_CENTIGRADES));
 	val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low / SMU_TEMPERATURE_UNITS_PER_CENTIGRADES));
 	val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK);
@@ -1181,6 +1183,7 @@ static int smu_v11_0_start_thermal_control(struct smu_context *smu)
 		ret = smu_v11_0_enable_thermal_alert(smu);
 		if (ret)
 			return ret;
+
 		ret = smu_set_thermal_fan_table(smu);
 		if (ret)
 			return ret;
@@ -1662,6 +1665,80 @@ static int smu_v11_0_set_xgmi_pstate(struct smu_context *smu,
 	return ret;
 }
 
+#define THM_11_0__SRCID__THM_DIG_THERM_L2H		0		/* ASIC_TEMP > CG_THERMAL_INT.DIG_THERM_INTH  */
+#define THM_11_0__SRCID__THM_DIG_THERM_H2L		1		/* ASIC_TEMP < CG_THERMAL_INT.DIG_THERM_INTL  */
+
+static int smu_v11_0_irq_process(struct amdgpu_device *adev,
+				 struct amdgpu_irq_src *source,
+				 struct amdgpu_iv_entry *entry)
+{
+	uint32_t client_id = entry->client_id;
+	uint32_t src_id = entry->src_id;
+
+	if (client_id == SOC15_IH_CLIENTID_THM) {
+		switch (src_id) {
+		case THM_11_0__SRCID__THM_DIG_THERM_L2H:
+			pr_warn("GPU over temperature range detected on PCIe %d:%d.%d!\n",
+				PCI_BUS_NUM(adev->pdev->devfn),
+				PCI_SLOT(adev->pdev->devfn),
+				PCI_FUNC(adev->pdev->devfn));
+		break;
+		case THM_11_0__SRCID__THM_DIG_THERM_H2L:
+			pr_warn("GPU under temperature range detected on PCIe %d:%d.%d!\n",
+				PCI_BUS_NUM(adev->pdev->devfn),
+				PCI_SLOT(adev->pdev->devfn),
+				PCI_FUNC(adev->pdev->devfn));
+		break;
+		default:
+			pr_warn("GPU under temperature range unknown src id (%d), detected on PCIe %d:%d.%d!\n",
+				src_id,
+				PCI_BUS_NUM(adev->pdev->devfn),
+				PCI_SLOT(adev->pdev->devfn),
+				PCI_FUNC(adev->pdev->devfn));
+		break;
+
+		}
+	}
+
+	return 0;
+}
+
+static const struct amdgpu_irq_src_funcs smu_v11_0_irq_funcs= {
+	.process = smu_v11_0_irq_process,
+};
+
+static int smu_v11_0_register_irq_handler(struct smu_context *smu)
+{
+	struct amdgpu_device *adev = smu->adev;
+	struct amdgpu_irq_src *irq_src = smu->irq_source;
+	int ret = 0;
+
+	/* already register */
+	if (irq_src)
+		return 0;
+
+	irq_src = kzalloc(sizeof(struct amdgpu_irq_src), GFP_KERNEL);
+	if (!irq_src)
+		return -ENOMEM;
+	smu->irq_source = irq_src;
+
+	irq_src->funcs = &smu_v11_0_irq_funcs;
+
+	ret = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_THM,
+				THM_11_0__SRCID__THM_DIG_THERM_L2H,
+				irq_src);
+	if (ret)
+		return ret;
+
+	ret = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_THM,
+				THM_11_0__SRCID__THM_DIG_THERM_H2L,
+				irq_src);
+	if (ret)
+		return ret;
+
+	return ret;
+}
+
 static const struct smu_funcs smu_v11_0_funcs = {
 	.init_microcode = smu_v11_0_init_microcode,
 	.load_microcode = smu_v11_0_load_microcode,
@@ -1711,6 +1788,7 @@ static const struct smu_funcs smu_v11_0_funcs = {
 	.set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm,
 	.set_xgmi_pstate = smu_v11_0_set_xgmi_pstate,
 	.gfx_off_control = smu_v11_0_gfx_off_control,
+	.register_irq_handler = smu_v11_0_register_irq_handler,
 };
 
 void smu_v11_0_set_smu_funcs(struct smu_context *smu)
-- 
2.20.1



More information about the amd-gfx mailing list