1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
30static u32 df_v3_6_channel_number[] = {1, 2, 0, 4, 0, 8, 0,
31 16, 32, 0, 0, 0, 2, 4, 8};
32
33
34AMDGPU_PMU_ATTR(event, "config:0-7");
35AMDGPU_PMU_ATTR(instance, "config:8-15");
36AMDGPU_PMU_ATTR(umask, "config:16-23");
37
38
39static 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
47static struct attribute_group df_v3_6_format_attr_group = {
48 .name = "format",
49 .attrs = df_v3_6_format_attrs,
50};
51
52
53AMDGPU_PMU_ATTR(cake0_pcsout_txdata,
54 "event=0x7,instance=0x46,umask=0x2");
55AMDGPU_PMU_ATTR(cake1_pcsout_txdata,
56 "event=0x7,instance=0x47,umask=0x2");
57AMDGPU_PMU_ATTR(cake0_pcsout_txmeta,
58 "event=0x7,instance=0x46,umask=0x4");
59AMDGPU_PMU_ATTR(cake1_pcsout_txmeta,
60 "event=0x7,instance=0x47,umask=0x4");
61AMDGPU_PMU_ATTR(cake0_ftiinstat_reqalloc,
62 "event=0xb,instance=0x46,umask=0x4");
63AMDGPU_PMU_ATTR(cake1_ftiinstat_reqalloc,
64 "event=0xb,instance=0x47,umask=0x4");
65AMDGPU_PMU_ATTR(cake0_ftiinstat_rspalloc,
66 "event=0xb,instance=0x46,umask=0x8");
67AMDGPU_PMU_ATTR(cake1_ftiinstat_rspalloc,
68 "event=0xb,instance=0x47,umask=0x8");
69
70
71static 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
84static struct attribute_group df_v3_6_event_attr_group = {
85 .name = "events",
86 .attrs = df_v3_6_event_attrs
87};
88
89
90const 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
97static 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
118static DEVICE_ATTR(df_cntr_avail, S_IRUGO, df_v3_6_get_df_cntr_avail, NULL);
119
120
121static 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
133static 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
147static 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
158static 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
169static void df_v3_6_update_medium_grain_clock_gating(struct amdgpu_device *adev,
170 bool enable)
171{
172 u32 tmp;
173
174
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
190 adev->df_funcs->enable_broadcast_mode(adev, false);
191}
192
193static void df_v3_6_get_clockgating_state(struct amdgpu_device *adev,
194 u32 *flags)
195{
196 u32 tmp;
197
198
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
205static 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
220static 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
255static 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
264static 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
299static 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
326static 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
336static 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
352static 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
382static 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
422static 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
458static 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
492const 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