Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu: Match TC hash settings to DF settings (v2)

On Arcturus, data fabric hashing is set by the VBIOS, and
affects which addresses map to which memory channels. The
gfx core's caches also need to know this mapping, but the
hash settings for these these caches is set by the driver.

This change queries the DF to understand how the VBIOS
configured DF, then matches the TC hash configuration bits
to do the same thing.

v2: squash in warning fix

Signed-off-by: Joseph Greathouse <Joseph.Greathouse@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Joseph Greathouse and committed by
Alex Deucher
22d39fe7 ae99fc35

+50
+3
drivers/gpu/drm/amd/amdgpu/df_v1_7.c
··· 31 31 32 32 static void df_v1_7_sw_init(struct amdgpu_device *adev) 33 33 { 34 + adev->df.hash_status.hash_64k = false; 35 + adev->df.hash_status.hash_2m = false; 36 + adev->df.hash_status.hash_1g = false; 34 37 } 35 38 36 39 static void df_v1_7_sw_fini(struct amdgpu_device *adev)
+28
drivers/gpu/drm/amd/amdgpu/df_v3_6.c
··· 262 262 /* device attr for available perfmon counters */ 263 263 static DEVICE_ATTR(df_cntr_avail, S_IRUGO, df_v3_6_get_df_cntr_avail, NULL); 264 264 265 + static void df_v3_6_query_hashes(struct amdgpu_device *adev) 266 + { 267 + u32 tmp; 268 + 269 + adev->df.hash_status.hash_64k = false; 270 + adev->df.hash_status.hash_2m = false; 271 + adev->df.hash_status.hash_1g = false; 272 + 273 + if (adev->asic_type != CHIP_ARCTURUS) 274 + return; 275 + 276 + /* encoding for hash-enabled on Arcturus */ 277 + if (adev->df.funcs->get_fb_channel_number(adev) == 0xe) { 278 + tmp = RREG32_SOC15(DF, 0, mmDF_CS_UMC_AON0_DfGlobalCtrl); 279 + adev->df.hash_status.hash_64k = REG_GET_FIELD(tmp, 280 + DF_CS_UMC_AON0_DfGlobalCtrl, 281 + GlbHashIntlvCtl64K); 282 + adev->df.hash_status.hash_2m = REG_GET_FIELD(tmp, 283 + DF_CS_UMC_AON0_DfGlobalCtrl, 284 + GlbHashIntlvCtl2M); 285 + adev->df.hash_status.hash_1g = REG_GET_FIELD(tmp, 286 + DF_CS_UMC_AON0_DfGlobalCtrl, 287 + GlbHashIntlvCtl1G); 288 + } 289 + } 290 + 265 291 /* init perfmons */ 266 292 static void df_v3_6_sw_init(struct amdgpu_device *adev) 267 293 { ··· 299 273 300 274 for (i = 0; i < AMDGPU_MAX_DF_PERFMONS; i++) 301 275 adev->df_perfmon_config_assign_mask[i] = 0; 276 + 277 + df_v3_6_query_hashes(adev); 302 278 } 303 279 304 280 static void df_v3_6_sw_fini(struct amdgpu_device *adev)
+19
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
··· 3637 3637 return 0; 3638 3638 } 3639 3639 3640 + static void gfx_v9_0_init_tcp_config(struct amdgpu_device *adev) 3641 + { 3642 + u32 tmp; 3643 + 3644 + if (adev->asic_type != CHIP_ARCTURUS) 3645 + return; 3646 + 3647 + tmp = RREG32_SOC15(GC, 0, mmTCP_ADDR_CONFIG); 3648 + tmp = REG_SET_FIELD(tmp, TCP_ADDR_CONFIG, ENABLE64KHASH, 3649 + adev->df.hash_status.hash_64k); 3650 + tmp = REG_SET_FIELD(tmp, TCP_ADDR_CONFIG, ENABLE2MHASH, 3651 + adev->df.hash_status.hash_2m); 3652 + tmp = REG_SET_FIELD(tmp, TCP_ADDR_CONFIG, ENABLE1GHASH, 3653 + adev->df.hash_status.hash_1g); 3654 + WREG32_SOC15(GC, 0, mmTCP_ADDR_CONFIG, tmp); 3655 + } 3656 + 3640 3657 static void gfx_v9_0_cp_enable(struct amdgpu_device *adev, bool enable) 3641 3658 { 3642 3659 if (adev->asic_type != CHIP_ARCTURUS) ··· 3670 3653 gfx_v9_0_init_golden_registers(adev); 3671 3654 3672 3655 gfx_v9_0_constants_init(adev); 3656 + 3657 + gfx_v9_0_init_tcp_config(adev); 3673 3658 3674 3659 r = adev->gfx.rlc.funcs->resume(adev); 3675 3660 if (r)