aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2596-drm-amd-powerplay-support-runtime-ppfeatures-setting.patch
blob: 7d8030260cc927e12bbf91de46050670ca312bfa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
From 61e2c3b487891fc346d7c6d89d9e436b82db8b85 Mon Sep 17 00:00:00 2001
From: Evan Quan <evan.quan@amd.com>
Date: Tue, 25 Jun 2019 11:06:08 +0800
Subject: [PATCH 2596/2940] drm/amd/powerplay: support runtime ppfeatures
 setting on Navi10

Implement Navi10 backend for runtime ppfeatures status retrieving
and setting support.

Change-Id: Ib498b934c260e351c6cafedcd865fd931319e7a3
Signed-off-by: Evan Quan <evan.quan@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
---
 drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 165 +++++++++++++++++++++
 1 file changed, 165 insertions(+)

diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index e2925e317201..99566de80572 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -1304,6 +1304,169 @@ static int navi10_get_uclk_dpm_states(struct smu_context *smu, uint32_t *clocks_
 	return 0;
 }
 
+static int navi10_get_ppfeature_status(struct smu_context *smu,
+				       char *buf)
+{
+	static const char *ppfeature_name[] = {
+				"DPM_PREFETCHER",
+				"DPM_GFXCLK",
+				"DPM_GFX_PACE",
+				"DPM_UCLK",
+				"DPM_SOCCLK",
+				"DPM_MP0CLK",
+				"DPM_LINK",
+				"DPM_DCEFCLK",
+				"MEM_VDDCI_SCALING",
+				"MEM_MVDD_SCALING",
+				"DS_GFXCLK",
+				"DS_SOCCLK",
+				"DS_LCLK",
+				"DS_DCEFCLK",
+				"DS_UCLK",
+				"GFX_ULV",
+				"FW_DSTATE",
+				"GFXOFF",
+				"BACO",
+				"VCN_PG",
+				"JPEG_PG",
+				"USB_PG",
+				"RSMU_SMN_CG",
+				"PPT",
+				"TDC",
+				"GFX_EDC",
+				"APCC_PLUS",
+				"GTHR",
+				"ACDC",
+				"VR0HOT",
+				"VR1HOT",
+				"FW_CTF",
+				"FAN_CONTROL",
+				"THERMAL",
+				"GFX_DCS",
+				"RM",
+				"LED_DISPLAY",
+				"GFX_SS",
+				"OUT_OF_BAND_MONITOR",
+				"TEMP_DEPENDENT_VMIN",
+				"MMHUB_PG",
+				"ATHUB_PG"};
+	static const char *output_title[] = {
+				"FEATURES",
+				"BITMASK",
+				"ENABLEMENT"};
+	uint64_t features_enabled;
+	uint32_t feature_mask[2];
+	int i;
+	int ret = 0;
+	int size = 0;
+
+	ret = smu_feature_get_enabled_mask(smu, feature_mask, 2);
+	PP_ASSERT_WITH_CODE(!ret,
+			"[GetPPfeatureStatus] Failed to get enabled smc features!",
+			return ret);
+	features_enabled = (uint64_t)feature_mask[0] |
+			   (uint64_t)feature_mask[1] << 32;
+
+	size += sprintf(buf + size, "Current ppfeatures: 0x%016llx\n", features_enabled);
+	size += sprintf(buf + size, "%-19s %-22s %s\n",
+				output_title[0],
+				output_title[1],
+				output_title[2]);
+	for (i = 0; i < (sizeof(ppfeature_name) / sizeof(ppfeature_name[0])); i++) {
+		size += sprintf(buf + size, "%-19s 0x%016llx %6s\n",
+					ppfeature_name[i],
+					1ULL << i,
+					(features_enabled & (1ULL << i)) ? "Y" : "N");
+	}
+
+	return size;
+}
+
+static int navi10_enable_smc_features(struct smu_context *smu,
+				      bool enabled,
+				      uint64_t feature_masks)
+{
+	struct smu_feature *feature = &smu->smu_feature;
+	uint32_t feature_low, feature_high;
+	uint32_t feature_mask[2];
+	int ret = 0;
+
+	feature_low = (uint32_t)(feature_masks & 0xFFFFFFFF);
+	feature_high = (uint32_t)((feature_masks & 0xFFFFFFFF00000000ULL) >> 32);
+
+	if (enabled) {
+		ret = smu_send_smc_msg_with_param(smu, SMU_MSG_EnableSmuFeaturesLow,
+						  feature_low);
+		if (ret)
+			return ret;
+		ret = smu_send_smc_msg_with_param(smu, SMU_MSG_EnableSmuFeaturesHigh,
+						  feature_high);
+		if (ret)
+			return ret;
+	} else {
+		ret = smu_send_smc_msg_with_param(smu, SMU_MSG_DisableSmuFeaturesLow,
+						  feature_low);
+		if (ret)
+			return ret;
+		ret = smu_send_smc_msg_with_param(smu, SMU_MSG_DisableSmuFeaturesHigh,
+						  feature_high);
+		if (ret)
+			return ret;
+	}
+
+	ret = smu_feature_get_enabled_mask(smu, feature_mask, 2);
+	if (ret)
+		return ret;
+
+	mutex_lock(&feature->mutex);
+	bitmap_copy(feature->enabled, (unsigned long *)&feature_mask,
+		    feature->feature_num);
+	mutex_unlock(&feature->mutex);
+
+	return 0;
+}
+
+static int navi10_set_ppfeature_status(struct smu_context *smu,
+				       uint64_t new_ppfeature_masks)
+{
+	uint64_t features_enabled;
+	uint32_t feature_mask[2];
+	uint64_t features_to_enable;
+	uint64_t features_to_disable;
+	int ret = 0;
+
+	ret = smu_feature_get_enabled_mask(smu, feature_mask, 2);
+	PP_ASSERT_WITH_CODE(!ret,
+			"[SetPPfeatureStatus] Failed to get enabled smc features!",
+			return ret);
+	features_enabled = (uint64_t)feature_mask[0] |
+			   (uint64_t)feature_mask[1] << 32;
+
+	features_to_disable =
+		features_enabled & ~new_ppfeature_masks;
+	features_to_enable =
+		~features_enabled & new_ppfeature_masks;
+
+	pr_debug("features_to_disable 0x%llx\n", features_to_disable);
+	pr_debug("features_to_enable 0x%llx\n", features_to_enable);
+
+	if (features_to_disable) {
+		ret = navi10_enable_smc_features(smu, false, features_to_disable);
+		PP_ASSERT_WITH_CODE(!ret,
+				"[SetPPfeatureStatus] Failed to disable smc features!",
+				return ret);
+	}
+
+	if (features_to_enable) {
+		ret = navi10_enable_smc_features(smu, true, features_to_enable);
+		PP_ASSERT_WITH_CODE(!ret,
+				"[SetPPfeatureStatus] Failed to enable smc features!",
+				return ret);
+	}
+
+	return 0;
+}
+
 static const struct pptable_funcs navi10_ppt_funcs = {
 	.tables_init = navi10_tables_init,
 	.alloc_dpm_context = navi10_allocate_dpm_context,
@@ -1337,6 +1500,8 @@ static const struct pptable_funcs navi10_ppt_funcs = {
 	.set_watermarks_table = navi10_set_watermarks_table,
 	.read_sensor = navi10_read_sensor,
 	.get_uclk_dpm_states = navi10_get_uclk_dpm_states,
+	.get_ppfeature_status = navi10_get_ppfeature_status,
+	.set_ppfeature_status = navi10_set_ppfeature_status,
 };
 
 void navi10_set_ppt_funcs(struct smu_context *smu)
-- 
2.17.1