]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/gpu/drm/amd/amdgpu/df_v3_6.c
Merge tag 'aspeed-5.4-devicetree' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / drivers / gpu / drm / amd / amdgpu / df_v3_6.c
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 };