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