xref: /openbmc/linux/drivers/gpu/drm/amd/amdgpu/df_v3_6.c (revision e8bd417a)
1 /*
2  * Copyright 2018 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  */
23 #include "amdgpu.h"
24 #include "df_v3_6.h"
25 
26 #include "df/df_3_6_default.h"
27 #include "df/df_3_6_offset.h"
28 #include "df/df_3_6_sh_mask.h"
29 
30 static u32 df_v3_6_channel_number[] = {1, 2, 0, 4, 0, 8, 0,
31 				       16, 32, 0, 0, 0, 2, 4, 8};
32 
33 /* init df format attrs */
34 AMDGPU_PMU_ATTR(event,		"config:0-7");
35 AMDGPU_PMU_ATTR(instance,	"config:8-15");
36 AMDGPU_PMU_ATTR(umask,		"config:16-23");
37 
38 /* df format attributes  */
39 static struct attribute *df_v3_6_format_attrs[] = {
40 	&pmu_attr_event.attr,
41 	&pmu_attr_instance.attr,
42 	&pmu_attr_umask.attr,
43 	NULL
44 };
45 
46 /* df format attribute group */
47 static struct attribute_group df_v3_6_format_attr_group = {
48 	.name = "format",
49 	.attrs = df_v3_6_format_attrs,
50 };
51 
52 /* df event attrs */
53 AMDGPU_PMU_ATTR(cake0_pcsout_txdata,
54 		      "event=0x7,instance=0x46,umask=0x2");
55 AMDGPU_PMU_ATTR(cake1_pcsout_txdata,
56 		      "event=0x7,instance=0x47,umask=0x2");
57 AMDGPU_PMU_ATTR(cake0_pcsout_txmeta,
58 		      "event=0x7,instance=0x46,umask=0x4");
59 AMDGPU_PMU_ATTR(cake1_pcsout_txmeta,
60 		      "event=0x7,instance=0x47,umask=0x4");
61 AMDGPU_PMU_ATTR(cake0_ftiinstat_reqalloc,
62 		      "event=0xb,instance=0x46,umask=0x4");
63 AMDGPU_PMU_ATTR(cake1_ftiinstat_reqalloc,
64 		      "event=0xb,instance=0x47,umask=0x4");
65 AMDGPU_PMU_ATTR(cake0_ftiinstat_rspalloc,
66 		      "event=0xb,instance=0x46,umask=0x8");
67 AMDGPU_PMU_ATTR(cake1_ftiinstat_rspalloc,
68 		      "event=0xb,instance=0x47,umask=0x8");
69 
70 /* df event attributes  */
71 static struct attribute *df_v3_6_event_attrs[] = {
72 	&pmu_attr_cake0_pcsout_txdata.attr,
73 	&pmu_attr_cake1_pcsout_txdata.attr,
74 	&pmu_attr_cake0_pcsout_txmeta.attr,
75 	&pmu_attr_cake1_pcsout_txmeta.attr,
76 	&pmu_attr_cake0_ftiinstat_reqalloc.attr,
77 	&pmu_attr_cake1_ftiinstat_reqalloc.attr,
78 	&pmu_attr_cake0_ftiinstat_rspalloc.attr,
79 	&pmu_attr_cake1_ftiinstat_rspalloc.attr,
80 	NULL
81 };
82 
83 /* df event attribute group */
84 static struct attribute_group df_v3_6_event_attr_group = {
85 	.name = "events",
86 	.attrs = df_v3_6_event_attrs
87 };
88 
89 /* df event attr groups  */
90 const struct attribute_group *df_v3_6_attr_groups[] = {
91 		&df_v3_6_format_attr_group,
92 		&df_v3_6_event_attr_group,
93 		NULL
94 };
95 
96 /* get the number of df counters available */
97 static ssize_t df_v3_6_get_df_cntr_avail(struct device *dev,
98 		struct device_attribute *attr,
99 		char *buf)
100 {
101 	struct amdgpu_device *adev;
102 	struct drm_device *ddev;
103 	int i, count;
104 
105 	ddev = dev_get_drvdata(dev);
106 	adev = ddev->dev_private;
107 	count = 0;
108 
109 	for (i = 0; i < DF_V3_6_MAX_COUNTERS; i++) {
110 		if (adev->df_perfmon_config_assign_mask[i] == 0)
111 			count++;
112 	}
113 
114 	return snprintf(buf, PAGE_SIZE,	"%i\n", count);
115 }
116 
117 /* device attr for available perfmon counters */
118 static DEVICE_ATTR(df_cntr_avail, S_IRUGO, df_v3_6_get_df_cntr_avail, NULL);
119 
120 /* init perfmons */
121 static void df_v3_6_sw_init(struct amdgpu_device *adev)
122 {
123 	int i, ret;
124 
125 	ret = device_create_file(adev->dev, &dev_attr_df_cntr_avail);
126 	if (ret)
127 		DRM_ERROR("failed to create file for available df counters\n");
128 
129 	for (i = 0; i < AMDGPU_MAX_DF_PERFMONS; i++)
130 		adev->df_perfmon_config_assign_mask[i] = 0;
131 }
132 
133 static void df_v3_6_enable_broadcast_mode(struct amdgpu_device *adev,
134 					  bool enable)
135 {
136 	u32 tmp;
137 
138 	if (enable) {
139 		tmp = RREG32_SOC15(DF, 0, mmFabricConfigAccessControl);
140 		tmp &= ~FabricConfigAccessControl__CfgRegInstAccEn_MASK;
141 		WREG32_SOC15(DF, 0, mmFabricConfigAccessControl, tmp);
142 	} else
143 		WREG32_SOC15(DF, 0, mmFabricConfigAccessControl,
144 			     mmFabricConfigAccessControl_DEFAULT);
145 }
146 
147 static u32 df_v3_6_get_fb_channel_number(struct amdgpu_device *adev)
148 {
149 	u32 tmp;
150 
151 	tmp = RREG32_SOC15(DF, 0, mmDF_CS_UMC_AON0_DramBaseAddress0);
152 	tmp &= DF_CS_UMC_AON0_DramBaseAddress0__IntLvNumChan_MASK;
153 	tmp >>= DF_CS_UMC_AON0_DramBaseAddress0__IntLvNumChan__SHIFT;
154 
155 	return tmp;
156 }
157 
158 static u32 df_v3_6_get_hbm_channel_number(struct amdgpu_device *adev)
159 {
160 	int fb_channel_number;
161 
162 	fb_channel_number = adev->df_funcs->get_fb_channel_number(adev);
163 	if (fb_channel_number >= ARRAY_SIZE(df_v3_6_channel_number))
164 		fb_channel_number = 0;
165 
166 	return df_v3_6_channel_number[fb_channel_number];
167 }
168 
169 static void df_v3_6_update_medium_grain_clock_gating(struct amdgpu_device *adev,
170 						     bool enable)
171 {
172 	u32 tmp;
173 
174 	/* Put DF on broadcast mode */
175 	adev->df_funcs->enable_broadcast_mode(adev, true);
176 
177 	if (enable && (adev->cg_flags & AMD_CG_SUPPORT_DF_MGCG)) {
178 		tmp = RREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater);
179 		tmp &= ~DF_PIE_AON0_DfGlobalClkGater__MGCGMode_MASK;
180 		tmp |= DF_V3_6_MGCG_ENABLE_15_CYCLE_DELAY;
181 		WREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater, tmp);
182 	} else {
183 		tmp = RREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater);
184 		tmp &= ~DF_PIE_AON0_DfGlobalClkGater__MGCGMode_MASK;
185 		tmp |= DF_V3_6_MGCG_DISABLE;
186 		WREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater, tmp);
187 	}
188 
189 	/* Exit broadcast mode */
190 	adev->df_funcs->enable_broadcast_mode(adev, false);
191 }
192 
193 static void df_v3_6_get_clockgating_state(struct amdgpu_device *adev,
194 					  u32 *flags)
195 {
196 	u32 tmp;
197 
198 	/* AMD_CG_SUPPORT_DF_MGCG */
199 	tmp = RREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater);
200 	if (tmp & DF_V3_6_MGCG_ENABLE_15_CYCLE_DELAY)
201 		*flags |= AMD_CG_SUPPORT_DF_MGCG;
202 }
203 
204 /* get assigned df perfmon ctr as int */
205 static int df_v3_6_pmc_config_2_cntr(struct amdgpu_device *adev,
206 				      uint64_t config)
207 {
208 	int i;
209 
210 	for (i = 0; i < DF_V3_6_MAX_COUNTERS; i++) {
211 		if ((config & 0x0FFFFFFUL) ==
212 					adev->df_perfmon_config_assign_mask[i])
213 			return i;
214 	}
215 
216 	return -EINVAL;
217 }
218 
219 /* get address based on counter assignment */
220 static void df_v3_6_pmc_get_addr(struct amdgpu_device *adev,
221 				 uint64_t config,
222 				 int is_ctrl,
223 				 uint32_t *lo_base_addr,
224 				 uint32_t *hi_base_addr)
225 {
226 	int target_cntr = df_v3_6_pmc_config_2_cntr(adev, config);
227 
228 	if (target_cntr < 0)
229 		return;
230 
231 	switch (target_cntr) {
232 
233 	case 0:
234 		*lo_base_addr = is_ctrl ? smnPerfMonCtlLo0 : smnPerfMonCtrLo0;
235 		*hi_base_addr = is_ctrl ? smnPerfMonCtlHi0 : smnPerfMonCtrHi0;
236 		break;
237 	case 1:
238 		*lo_base_addr = is_ctrl ? smnPerfMonCtlLo1 : smnPerfMonCtrLo1;
239 		*hi_base_addr = is_ctrl ? smnPerfMonCtlHi1 : smnPerfMonCtrHi1;
240 		break;
241 	case 2:
242 		*lo_base_addr = is_ctrl ? smnPerfMonCtlLo2 : smnPerfMonCtrLo2;
243 		*hi_base_addr = is_ctrl ? smnPerfMonCtlHi2 : smnPerfMonCtrHi2;
244 		break;
245 	case 3:
246 		*lo_base_addr = is_ctrl ? smnPerfMonCtlLo3 : smnPerfMonCtrLo3;
247 		*hi_base_addr = is_ctrl ? smnPerfMonCtlHi3 : smnPerfMonCtrHi3;
248 		break;
249 
250 	}
251 
252 }
253 
254 /* get read counter address */
255 static void df_v3_6_pmc_get_read_settings(struct amdgpu_device *adev,
256 					  uint64_t config,
257 					  uint32_t *lo_base_addr,
258 					  uint32_t *hi_base_addr)
259 {
260 	df_v3_6_pmc_get_addr(adev, config, 0, lo_base_addr, hi_base_addr);
261 }
262 
263 /* get control counter settings i.e. address and values to set */
264 static int df_v3_6_pmc_get_ctrl_settings(struct amdgpu_device *adev,
265 					  uint64_t config,
266 					  uint32_t *lo_base_addr,
267 					  uint32_t *hi_base_addr,
268 					  uint32_t *lo_val,
269 					  uint32_t *hi_val)
270 {
271 	df_v3_6_pmc_get_addr(adev, config, 1, lo_base_addr, hi_base_addr);
272 
273 	if ((*lo_base_addr == 0) || (*hi_base_addr == 0)) {
274 		DRM_ERROR("[DF PMC] addressing not retrieved! Lo: %x, Hi: %x",
275 				*lo_base_addr, *hi_base_addr);
276 		return -ENXIO;
277 	}
278 
279 	if (lo_val && hi_val) {
280 		uint32_t eventsel, instance, unitmask;
281 		uint32_t instance_10, instance_5432, instance_76;
282 
283 		eventsel = DF_V3_6_GET_EVENT(config) & 0x3f;
284 		unitmask = DF_V3_6_GET_UNITMASK(config) & 0xf;
285 		instance = DF_V3_6_GET_INSTANCE(config);
286 
287 		instance_10 = instance & 0x3;
288 		instance_5432 = (instance >> 2) & 0xf;
289 		instance_76 = (instance >> 6) & 0x3;
290 
291 		*lo_val = (unitmask << 8) | (instance_10 << 6) | eventsel;
292 		*hi_val = (instance_76 << 29) | instance_5432;
293 	}
294 
295 	return 0;
296 }
297 
298 /* assign df performance counters for read */
299 static int df_v3_6_pmc_assign_cntr(struct amdgpu_device *adev,
300 				   uint64_t config,
301 				   int *is_assigned)
302 {
303 	int i, target_cntr;
304 
305 	*is_assigned = 0;
306 
307 	target_cntr = df_v3_6_pmc_config_2_cntr(adev, config);
308 
309 	if (target_cntr >= 0) {
310 		*is_assigned = 1;
311 		return 0;
312 	}
313 
314 	for (i = 0; i < DF_V3_6_MAX_COUNTERS; i++) {
315 		if (adev->df_perfmon_config_assign_mask[i] == 0U) {
316 			adev->df_perfmon_config_assign_mask[i] =
317 							config & 0x0FFFFFFUL;
318 			return 0;
319 		}
320 	}
321 
322 	return -ENOSPC;
323 }
324 
325 /* release performance counter */
326 static void df_v3_6_pmc_release_cntr(struct amdgpu_device *adev,
327 				     uint64_t config)
328 {
329 	int target_cntr = df_v3_6_pmc_config_2_cntr(adev, config);
330 
331 	if (target_cntr >= 0)
332 		adev->df_perfmon_config_assign_mask[target_cntr] = 0ULL;
333 }
334 
335 
336 static void df_v3_6_reset_perfmon_cntr(struct amdgpu_device *adev,
337 					 uint64_t config)
338 {
339 	uint32_t lo_base_addr, hi_base_addr;
340 
341 	df_v3_6_pmc_get_read_settings(adev, config, &lo_base_addr,
342 				      &hi_base_addr);
343 
344 	if ((lo_base_addr == 0) || (hi_base_addr == 0))
345 		return;
346 
347 	WREG32_PCIE(lo_base_addr, 0UL);
348 	WREG32_PCIE(hi_base_addr, 0UL);
349 }
350 
351 
352 static int df_v3_6_add_perfmon_cntr(struct amdgpu_device *adev,
353 				      uint64_t config)
354 {
355 	uint32_t lo_base_addr, hi_base_addr, lo_val, hi_val;
356 	int ret, is_assigned;
357 
358 	ret = df_v3_6_pmc_assign_cntr(adev, config, &is_assigned);
359 
360 	if (ret || is_assigned)
361 		return ret;
362 
363 	ret = df_v3_6_pmc_get_ctrl_settings(adev,
364 			config,
365 			&lo_base_addr,
366 			&hi_base_addr,
367 			&lo_val,
368 			&hi_val);
369 
370 	if (ret)
371 		return ret;
372 
373 	DRM_DEBUG_DRIVER("config=%llx addr=%08x:%08x val=%08x:%08x",
374 			config, lo_base_addr, hi_base_addr, lo_val, hi_val);
375 
376 	WREG32_PCIE(lo_base_addr, lo_val);
377 	WREG32_PCIE(hi_base_addr, hi_val);
378 
379 	return ret;
380 }
381 
382 static int df_v3_6_pmc_start(struct amdgpu_device *adev, uint64_t config,
383 			     int is_enable)
384 {
385 	uint32_t lo_base_addr, hi_base_addr, lo_val;
386 	int ret = 0;
387 
388 	switch (adev->asic_type) {
389 	case CHIP_VEGA20:
390 
391 		df_v3_6_reset_perfmon_cntr(adev, config);
392 
393 		if (is_enable) {
394 			ret = df_v3_6_add_perfmon_cntr(adev, config);
395 		} else {
396 			ret = df_v3_6_pmc_get_ctrl_settings(adev,
397 					config,
398 					&lo_base_addr,
399 					&hi_base_addr,
400 					NULL,
401 					NULL);
402 
403 			if (ret)
404 				return ret;
405 
406 			lo_val = RREG32_PCIE(lo_base_addr);
407 
408 			DRM_DEBUG_DRIVER("config=%llx addr=%08x:%08x val=%08x",
409 				config, lo_base_addr, hi_base_addr, lo_val);
410 
411 			WREG32_PCIE(lo_base_addr, lo_val | (1ULL << 22));
412 		}
413 
414 		break;
415 	default:
416 		break;
417 	}
418 
419 	return ret;
420 }
421 
422 static int df_v3_6_pmc_stop(struct amdgpu_device *adev, uint64_t config,
423 			    int is_disable)
424 {
425 	uint32_t lo_base_addr, hi_base_addr, lo_val;
426 	int ret = 0;
427 
428 	switch (adev->asic_type) {
429 	case CHIP_VEGA20:
430 		ret = df_v3_6_pmc_get_ctrl_settings(adev,
431 			config,
432 			&lo_base_addr,
433 			&hi_base_addr,
434 			NULL,
435 			NULL);
436 
437 		if (ret)
438 			return ret;
439 
440 		lo_val = RREG32_PCIE(lo_base_addr);
441 
442 		DRM_DEBUG_DRIVER("config=%llx addr=%08x:%08x val=%08x",
443 				config, lo_base_addr, hi_base_addr, lo_val);
444 
445 		WREG32_PCIE(lo_base_addr, lo_val & ~(1ULL << 22));
446 
447 		if (is_disable)
448 			df_v3_6_pmc_release_cntr(adev, config);
449 
450 		break;
451 	default:
452 		break;
453 	}
454 
455 	return ret;
456 }
457 
458 static void df_v3_6_pmc_get_count(struct amdgpu_device *adev,
459 				  uint64_t config,
460 				  uint64_t *count)
461 {
462 	uint32_t lo_base_addr, hi_base_addr, lo_val, hi_val;
463 	*count = 0;
464 
465 	switch (adev->asic_type) {
466 	case CHIP_VEGA20:
467 
468 		df_v3_6_pmc_get_read_settings(adev, config, &lo_base_addr,
469 				      &hi_base_addr);
470 
471 		if ((lo_base_addr == 0) || (hi_base_addr == 0))
472 			return;
473 
474 		lo_val = RREG32_PCIE(lo_base_addr);
475 		hi_val = RREG32_PCIE(hi_base_addr);
476 
477 		*count  = ((hi_val | 0ULL) << 32) | (lo_val | 0ULL);
478 
479 		if (*count >= DF_V3_6_PERFMON_OVERFLOW)
480 			*count = 0;
481 
482 		DRM_DEBUG_DRIVER("config=%llx addr=%08x:%08x val=%08x:%08x",
483 			config, lo_base_addr, hi_base_addr, lo_val, hi_val);
484 
485 		break;
486 
487 	default:
488 		break;
489 	}
490 }
491 
492 const struct amdgpu_df_funcs df_v3_6_funcs = {
493 	.sw_init = df_v3_6_sw_init,
494 	.enable_broadcast_mode = df_v3_6_enable_broadcast_mode,
495 	.get_fb_channel_number = df_v3_6_get_fb_channel_number,
496 	.get_hbm_channel_number = df_v3_6_get_hbm_channel_number,
497 	.update_medium_grain_clock_gating =
498 			df_v3_6_update_medium_grain_clock_gating,
499 	.get_clockgating_state = df_v3_6_get_clockgating_state,
500 	.pmc_start = df_v3_6_pmc_start,
501 	.pmc_stop = df_v3_6_pmc_stop,
502 	.pmc_get_count = df_v3_6_pmc_get_count
503 };
504