2 * Copyright 2018 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
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"
30 static u32 df_v3_6_channel_number[] = {1, 2, 0, 4, 0, 8, 0,
31 16, 32, 0, 0, 0, 2, 4, 8};
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");
38 /* df format attributes */
39 static struct attribute *df_v3_6_format_attrs[] = {
41 &pmu_attr_instance.attr,
46 /* df format attribute group */
47 static struct attribute_group df_v3_6_format_attr_group = {
49 .attrs = df_v3_6_format_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");
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,
83 /* df event attribute group */
84 static struct attribute_group df_v3_6_event_attr_group = {
86 .attrs = df_v3_6_event_attrs
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,
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,
101 struct amdgpu_device *adev;
102 struct drm_device *ddev;
105 ddev = dev_get_drvdata(dev);
106 adev = ddev->dev_private;
109 for (i = 0; i < DF_V3_6_MAX_COUNTERS; i++) {
110 if (adev->df_perfmon_config_assign_mask[i] == 0)
114 return snprintf(buf, PAGE_SIZE, "%i\n", count);
117 /* device attr for available perfmon counters */
118 static DEVICE_ATTR(df_cntr_avail, S_IRUGO, df_v3_6_get_df_cntr_avail, NULL);
121 static void df_v3_6_sw_init(struct amdgpu_device *adev)
125 ret = device_create_file(adev->dev, &dev_attr_df_cntr_avail);
127 DRM_ERROR("failed to create file for available df counters\n");
129 for (i = 0; i < AMDGPU_MAX_DF_PERFMONS; i++)
130 adev->df_perfmon_config_assign_mask[i] = 0;
133 static void df_v3_6_enable_broadcast_mode(struct amdgpu_device *adev,
139 tmp = RREG32_SOC15(DF, 0, mmFabricConfigAccessControl);
140 tmp &= ~FabricConfigAccessControl__CfgRegInstAccEn_MASK;
141 WREG32_SOC15(DF, 0, mmFabricConfigAccessControl, tmp);
143 WREG32_SOC15(DF, 0, mmFabricConfigAccessControl,
144 mmFabricConfigAccessControl_DEFAULT);
147 static u32 df_v3_6_get_fb_channel_number(struct amdgpu_device *adev)
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;
158 static u32 df_v3_6_get_hbm_channel_number(struct amdgpu_device *adev)
160 int fb_channel_number;
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;
166 return df_v3_6_channel_number[fb_channel_number];
169 static void df_v3_6_update_medium_grain_clock_gating(struct amdgpu_device *adev,
174 /* Put DF on broadcast mode */
175 adev->df_funcs->enable_broadcast_mode(adev, true);
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);
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);
189 /* Exit broadcast mode */
190 adev->df_funcs->enable_broadcast_mode(adev, false);
193 static void df_v3_6_get_clockgating_state(struct amdgpu_device *adev,
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;
204 /* get assigned df perfmon ctr as int */
205 static int df_v3_6_pmc_config_2_cntr(struct amdgpu_device *adev,
210 for (i = 0; i < DF_V3_6_MAX_COUNTERS; i++) {
211 if ((config & 0x0FFFFFFUL) ==
212 adev->df_perfmon_config_assign_mask[i])
219 /* get address based on counter assignment */
220 static void df_v3_6_pmc_get_addr(struct amdgpu_device *adev,
223 uint32_t *lo_base_addr,
224 uint32_t *hi_base_addr)
226 int target_cntr = df_v3_6_pmc_config_2_cntr(adev, config);
231 switch (target_cntr) {
234 *lo_base_addr = is_ctrl ? smnPerfMonCtlLo0 : smnPerfMonCtrLo0;
235 *hi_base_addr = is_ctrl ? smnPerfMonCtlHi0 : smnPerfMonCtrHi0;
238 *lo_base_addr = is_ctrl ? smnPerfMonCtlLo1 : smnPerfMonCtrLo1;
239 *hi_base_addr = is_ctrl ? smnPerfMonCtlHi1 : smnPerfMonCtrHi1;
242 *lo_base_addr = is_ctrl ? smnPerfMonCtlLo2 : smnPerfMonCtrLo2;
243 *hi_base_addr = is_ctrl ? smnPerfMonCtlHi2 : smnPerfMonCtrHi2;
246 *lo_base_addr = is_ctrl ? smnPerfMonCtlLo3 : smnPerfMonCtrLo3;
247 *hi_base_addr = is_ctrl ? smnPerfMonCtlHi3 : smnPerfMonCtrHi3;
254 /* get read counter address */
255 static void df_v3_6_pmc_get_read_settings(struct amdgpu_device *adev,
257 uint32_t *lo_base_addr,
258 uint32_t *hi_base_addr)
260 df_v3_6_pmc_get_addr(adev, config, 0, lo_base_addr, hi_base_addr);
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,
266 uint32_t *lo_base_addr,
267 uint32_t *hi_base_addr,
271 df_v3_6_pmc_get_addr(adev, config, 1, lo_base_addr, hi_base_addr);
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);
279 if (lo_val && hi_val) {
280 uint32_t eventsel, instance, unitmask;
281 uint32_t instance_10, instance_5432, instance_76;
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);
287 instance_10 = instance & 0x3;
288 instance_5432 = (instance >> 2) & 0xf;
289 instance_76 = (instance >> 6) & 0x3;
291 *lo_val = (unitmask << 8) | (instance_10 << 6) | eventsel;
292 *hi_val = (instance_76 << 29) | instance_5432;
298 /* assign df performance counters for read */
299 static int df_v3_6_pmc_assign_cntr(struct amdgpu_device *adev,
307 target_cntr = df_v3_6_pmc_config_2_cntr(adev, config);
309 if (target_cntr >= 0) {
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;
325 /* release performance counter */
326 static void df_v3_6_pmc_release_cntr(struct amdgpu_device *adev,
329 int target_cntr = df_v3_6_pmc_config_2_cntr(adev, config);
331 if (target_cntr >= 0)
332 adev->df_perfmon_config_assign_mask[target_cntr] = 0ULL;
336 static void df_v3_6_reset_perfmon_cntr(struct amdgpu_device *adev,
339 uint32_t lo_base_addr, hi_base_addr;
341 df_v3_6_pmc_get_read_settings(adev, config, &lo_base_addr,
344 if ((lo_base_addr == 0) || (hi_base_addr == 0))
347 WREG32_PCIE(lo_base_addr, 0UL);
348 WREG32_PCIE(hi_base_addr, 0UL);
352 static int df_v3_6_add_perfmon_cntr(struct amdgpu_device *adev,
355 uint32_t lo_base_addr, hi_base_addr, lo_val, hi_val;
356 int ret, is_assigned;
358 ret = df_v3_6_pmc_assign_cntr(adev, config, &is_assigned);
360 if (ret || is_assigned)
363 ret = df_v3_6_pmc_get_ctrl_settings(adev,
373 DRM_DEBUG_DRIVER("config=%llx addr=%08x:%08x val=%08x:%08x",
374 config, lo_base_addr, hi_base_addr, lo_val, hi_val);
376 WREG32_PCIE(lo_base_addr, lo_val);
377 WREG32_PCIE(hi_base_addr, hi_val);
382 static int df_v3_6_pmc_start(struct amdgpu_device *adev, uint64_t config,
385 uint32_t lo_base_addr, hi_base_addr, lo_val;
388 switch (adev->asic_type) {
391 df_v3_6_reset_perfmon_cntr(adev, config);
394 ret = df_v3_6_add_perfmon_cntr(adev, config);
396 ret = df_v3_6_pmc_get_ctrl_settings(adev,
406 lo_val = RREG32_PCIE(lo_base_addr);
408 DRM_DEBUG_DRIVER("config=%llx addr=%08x:%08x val=%08x",
409 config, lo_base_addr, hi_base_addr, lo_val);
411 WREG32_PCIE(lo_base_addr, lo_val | (1ULL << 22));
422 static int df_v3_6_pmc_stop(struct amdgpu_device *adev, uint64_t config,
425 uint32_t lo_base_addr, hi_base_addr, lo_val;
428 switch (adev->asic_type) {
430 ret = df_v3_6_pmc_get_ctrl_settings(adev,
440 lo_val = RREG32_PCIE(lo_base_addr);
442 DRM_DEBUG_DRIVER("config=%llx addr=%08x:%08x val=%08x",
443 config, lo_base_addr, hi_base_addr, lo_val);
445 WREG32_PCIE(lo_base_addr, lo_val & ~(1ULL << 22));
448 df_v3_6_pmc_release_cntr(adev, config);
458 static void df_v3_6_pmc_get_count(struct amdgpu_device *adev,
462 uint32_t lo_base_addr, hi_base_addr, lo_val, hi_val;
465 switch (adev->asic_type) {
468 df_v3_6_pmc_get_read_settings(adev, config, &lo_base_addr,
471 if ((lo_base_addr == 0) || (hi_base_addr == 0))
474 lo_val = RREG32_PCIE(lo_base_addr);
475 hi_val = RREG32_PCIE(hi_base_addr);
477 *count = ((hi_val | 0ULL) << 32) | (lo_val | 0ULL);
479 if (*count >= DF_V3_6_PERFMON_OVERFLOW)
482 DRM_DEBUG_DRIVER("config=%llx addr=%08x:%08x val=%08x:%08x",
483 config, lo_base_addr, hi_base_addr, lo_val, hi_val);
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