brintos

brintos / linux-shallow public Read only

0
0
Text · 18.5 KiB · 483a441 Raw
686 lines · c
1/*2 * Copyright 2018 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * 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 OR20 * 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#define DF_3_6_SMN_REG_INST_DIST        0x831#define DF_3_6_INST_CNT                 832 33/* Defined in global_features.h as FTI_PERFMON_VISIBLE */34#define DF_V3_6_MAX_COUNTERS		435 36/* get flags from df perfmon config */37#define DF_V3_6_GET_EVENT(x)		(x & 0xFFUL)38#define DF_V3_6_GET_INSTANCE(x)		((x >> 8) & 0xFFUL)39#define DF_V3_6_GET_UNITMASK(x)		((x >> 16) & 0xFFUL)40#define DF_V3_6_PERFMON_OVERFLOW	0xFFFFFFFFFFFFULL41 42static u32 df_v3_6_channel_number[] = {1, 2, 0, 4, 0, 8, 0,43				       16, 32, 0, 0, 0, 2, 4, 8};44 45static uint64_t df_v3_6_get_fica(struct amdgpu_device *adev,46				 uint32_t ficaa_val)47{48	unsigned long flags, address, data;49	uint32_t ficadl_val, ficadh_val;50 51	address = adev->nbio.funcs->get_pcie_index_offset(adev);52	data = adev->nbio.funcs->get_pcie_data_offset(adev);53 54	spin_lock_irqsave(&adev->pcie_idx_lock, flags);55	WREG32(address, smnDF_PIE_AON_FabricIndirectConfigAccessAddress3);56	WREG32(data, ficaa_val);57 58	WREG32(address, smnDF_PIE_AON_FabricIndirectConfigAccessDataLo3);59	ficadl_val = RREG32(data);60 61	WREG32(address, smnDF_PIE_AON_FabricIndirectConfigAccessDataHi3);62	ficadh_val = RREG32(data);63 64	spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);65 66	return (((ficadh_val & 0xFFFFFFFFFFFFFFFF) << 32) | ficadl_val);67}68 69static void df_v3_6_set_fica(struct amdgpu_device *adev, uint32_t ficaa_val,70			     uint32_t ficadl_val, uint32_t ficadh_val)71{72	unsigned long flags, address, data;73 74	address = adev->nbio.funcs->get_pcie_index_offset(adev);75	data = adev->nbio.funcs->get_pcie_data_offset(adev);76 77	spin_lock_irqsave(&adev->pcie_idx_lock, flags);78	WREG32(address, smnDF_PIE_AON_FabricIndirectConfigAccessAddress3);79	WREG32(data, ficaa_val);80 81	WREG32(address, smnDF_PIE_AON_FabricIndirectConfigAccessDataLo3);82	WREG32(data, ficadl_val);83 84	WREG32(address, smnDF_PIE_AON_FabricIndirectConfigAccessDataHi3);85	WREG32(data, ficadh_val);86 87	spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);88}89 90/*91 * df_v3_6_perfmon_rreg - read perfmon lo and hi92 *93 * required to be atomic.  no mmio method provided so subsequent reads for lo94 * and hi require to preserve df finite state machine95 */96static void df_v3_6_perfmon_rreg(struct amdgpu_device *adev,97			    uint32_t lo_addr, uint32_t *lo_val,98			    uint32_t hi_addr, uint32_t *hi_val)99{100	unsigned long flags, address, data;101 102	address = adev->nbio.funcs->get_pcie_index_offset(adev);103	data = adev->nbio.funcs->get_pcie_data_offset(adev);104 105	spin_lock_irqsave(&adev->pcie_idx_lock, flags);106	WREG32(address, lo_addr);107	*lo_val = RREG32(data);108	WREG32(address, hi_addr);109	*hi_val = RREG32(data);110	spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);111}112 113/*114 * df_v3_6_perfmon_wreg - write to perfmon lo and hi115 *116 * required to be atomic.  no mmio method provided so subsequent reads after117 * data writes cannot occur to preserve data fabrics finite state machine.118 */119static void df_v3_6_perfmon_wreg(struct amdgpu_device *adev, uint32_t lo_addr,120			    uint32_t lo_val, uint32_t hi_addr, uint32_t hi_val)121{122	unsigned long flags, address, data;123 124	address = adev->nbio.funcs->get_pcie_index_offset(adev);125	data = adev->nbio.funcs->get_pcie_data_offset(adev);126 127	spin_lock_irqsave(&adev->pcie_idx_lock, flags);128	WREG32(address, lo_addr);129	WREG32(data, lo_val);130	WREG32(address, hi_addr);131	WREG32(data, hi_val);132	spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);133}134 135/* same as perfmon_wreg but return status on write value check */136static int df_v3_6_perfmon_arm_with_status(struct amdgpu_device *adev,137					  uint32_t lo_addr, uint32_t lo_val,138					  uint32_t hi_addr, uint32_t  hi_val)139{140	unsigned long flags, address, data;141	uint32_t lo_val_rb, hi_val_rb;142 143	address = adev->nbio.funcs->get_pcie_index_offset(adev);144	data = adev->nbio.funcs->get_pcie_data_offset(adev);145 146	spin_lock_irqsave(&adev->pcie_idx_lock, flags);147	WREG32(address, lo_addr);148	WREG32(data, lo_val);149	WREG32(address, hi_addr);150	WREG32(data, hi_val);151 152	WREG32(address, lo_addr);153	lo_val_rb = RREG32(data);154	WREG32(address, hi_addr);155	hi_val_rb = RREG32(data);156	spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);157 158	if (!(lo_val == lo_val_rb && hi_val == hi_val_rb))159		return -EBUSY;160 161	return 0;162}163 164 165/*166 * retry arming counters every 100 usecs within 1 millisecond interval.167 * if retry fails after time out, return error.168 */169#define ARM_RETRY_USEC_TIMEOUT	1000170#define ARM_RETRY_USEC_INTERVAL	100171static int df_v3_6_perfmon_arm_with_retry(struct amdgpu_device *adev,172					  uint32_t lo_addr, uint32_t lo_val,173					  uint32_t hi_addr, uint32_t  hi_val)174{175	int countdown = ARM_RETRY_USEC_TIMEOUT;176 177	while (countdown) {178 179		if (!df_v3_6_perfmon_arm_with_status(adev, lo_addr, lo_val,180						     hi_addr, hi_val))181			break;182 183		countdown -= ARM_RETRY_USEC_INTERVAL;184		udelay(ARM_RETRY_USEC_INTERVAL);185	}186 187	return countdown > 0 ? 0 : -ETIME;188}189 190/* get the number of df counters available */191static ssize_t df_v3_6_get_df_cntr_avail(struct device *dev,192		struct device_attribute *attr,193		char *buf)194{195	struct amdgpu_device *adev;196	struct drm_device *ddev;197	int i, count;198 199	ddev = dev_get_drvdata(dev);200	adev = drm_to_adev(ddev);201	count = 0;202 203	for (i = 0; i < DF_V3_6_MAX_COUNTERS; i++) {204		if (adev->df_perfmon_config_assign_mask[i] == 0)205			count++;206	}207 208	return sysfs_emit(buf, "%i\n", count);209}210 211/* device attr for available perfmon counters */212static DEVICE_ATTR(df_cntr_avail, S_IRUGO, df_v3_6_get_df_cntr_avail, NULL);213 214static void df_v3_6_query_hashes(struct amdgpu_device *adev)215{216	u32 tmp;217 218	adev->df.hash_status.hash_64k = false;219	adev->df.hash_status.hash_2m = false;220	adev->df.hash_status.hash_1g = false;221 222	/* encoding for hash-enabled on Arcturus and Aldebaran */223	if ((adev->asic_type == CHIP_ARCTURUS &&224	     adev->df.funcs->get_fb_channel_number(adev) == 0xe) ||225	     (adev->asic_type == CHIP_ALDEBARAN &&226	      adev->df.funcs->get_fb_channel_number(adev) == 0x1e)) {227		tmp = RREG32_SOC15(DF, 0, mmDF_CS_UMC_AON0_DfGlobalCtrl);228		adev->df.hash_status.hash_64k = REG_GET_FIELD(tmp,229						DF_CS_UMC_AON0_DfGlobalCtrl,230						GlbHashIntlvCtl64K);231		adev->df.hash_status.hash_2m = REG_GET_FIELD(tmp,232						DF_CS_UMC_AON0_DfGlobalCtrl,233						GlbHashIntlvCtl2M);234		adev->df.hash_status.hash_1g = REG_GET_FIELD(tmp,235						DF_CS_UMC_AON0_DfGlobalCtrl,236						GlbHashIntlvCtl1G);237	}238}239 240/* init perfmons */241static void df_v3_6_sw_init(struct amdgpu_device *adev)242{243	int i, ret;244 245	ret = device_create_file(adev->dev, &dev_attr_df_cntr_avail);246	if (ret)247		DRM_ERROR("failed to create file for available df counters\n");248 249	for (i = 0; i < AMDGPU_MAX_DF_PERFMONS; i++)250		adev->df_perfmon_config_assign_mask[i] = 0;251 252	df_v3_6_query_hashes(adev);253}254 255static void df_v3_6_sw_fini(struct amdgpu_device *adev)256{257 258	device_remove_file(adev->dev, &dev_attr_df_cntr_avail);259 260}261 262static void df_v3_6_enable_broadcast_mode(struct amdgpu_device *adev,263					  bool enable)264{265	u32 tmp;266 267	if (enable) {268		tmp = RREG32_SOC15(DF, 0, mmFabricConfigAccessControl);269		tmp &= ~FabricConfigAccessControl__CfgRegInstAccEn_MASK;270		WREG32_SOC15(DF, 0, mmFabricConfigAccessControl, tmp);271	} else272		WREG32_SOC15(DF, 0, mmFabricConfigAccessControl,273			     mmFabricConfigAccessControl_DEFAULT);274}275 276static u32 df_v3_6_get_fb_channel_number(struct amdgpu_device *adev)277{278	u32 tmp;279 280	if (adev->asic_type == CHIP_ALDEBARAN) {281		tmp = RREG32_SOC15(DF, 0, mmDF_GCM_AON0_DramMegaBaseAddress0);282		tmp &=283		ALDEBARAN_DF_CS_UMC_AON0_DramBaseAddress0__IntLvNumChan_MASK;284	} else {285		tmp = RREG32_SOC15(DF, 0, mmDF_CS_UMC_AON0_DramBaseAddress0);286		tmp &= DF_CS_UMC_AON0_DramBaseAddress0__IntLvNumChan_MASK;287	}288	tmp >>= DF_CS_UMC_AON0_DramBaseAddress0__IntLvNumChan__SHIFT;289 290	return tmp;291}292 293static u32 df_v3_6_get_hbm_channel_number(struct amdgpu_device *adev)294{295	int fb_channel_number;296 297	fb_channel_number = adev->df.funcs->get_fb_channel_number(adev);298	if (fb_channel_number >= ARRAY_SIZE(df_v3_6_channel_number))299		fb_channel_number = 0;300 301	return df_v3_6_channel_number[fb_channel_number];302}303 304static void df_v3_6_update_medium_grain_clock_gating(struct amdgpu_device *adev,305						     bool enable)306{307	u32 tmp;308 309	if (adev->cg_flags & AMD_CG_SUPPORT_DF_MGCG) {310		/* Put DF on broadcast mode */311		adev->df.funcs->enable_broadcast_mode(adev, true);312 313		if (enable) {314			tmp = RREG32_SOC15(DF, 0,315					mmDF_PIE_AON0_DfGlobalClkGater);316			tmp &= ~DF_PIE_AON0_DfGlobalClkGater__MGCGMode_MASK;317			tmp |= DF_V3_6_MGCG_ENABLE_15_CYCLE_DELAY;318			WREG32_SOC15(DF, 0,319					mmDF_PIE_AON0_DfGlobalClkGater, tmp);320		} else {321			tmp = RREG32_SOC15(DF, 0,322					mmDF_PIE_AON0_DfGlobalClkGater);323			tmp &= ~DF_PIE_AON0_DfGlobalClkGater__MGCGMode_MASK;324			tmp |= DF_V3_6_MGCG_DISABLE;325			WREG32_SOC15(DF, 0,326					mmDF_PIE_AON0_DfGlobalClkGater, tmp);327		}328 329		/* Exit broadcast mode */330		adev->df.funcs->enable_broadcast_mode(adev, false);331	}332}333 334static void df_v3_6_get_clockgating_state(struct amdgpu_device *adev,335					  u64 *flags)336{337	u32 tmp;338 339	/* AMD_CG_SUPPORT_DF_MGCG */340	tmp = RREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater);341	if (tmp & DF_V3_6_MGCG_ENABLE_15_CYCLE_DELAY)342		*flags |= AMD_CG_SUPPORT_DF_MGCG;343}344 345/* get assigned df perfmon ctr as int */346static bool df_v3_6_pmc_has_counter(struct amdgpu_device *adev,347				      uint64_t config,348				      int counter_idx)349{350 351	return ((config & 0x0FFFFFFUL) ==352			adev->df_perfmon_config_assign_mask[counter_idx]);353 354}355 356/* get address based on counter assignment */357static void df_v3_6_pmc_get_addr(struct amdgpu_device *adev,358				 uint64_t config,359				 int counter_idx,360				 int is_ctrl,361				 uint32_t *lo_base_addr,362				 uint32_t *hi_base_addr)363{364	if (!df_v3_6_pmc_has_counter(adev, config, counter_idx))365		return;366 367	switch (counter_idx) {368 369	case 0:370		*lo_base_addr = is_ctrl ? smnPerfMonCtlLo4 : smnPerfMonCtrLo4;371		*hi_base_addr = is_ctrl ? smnPerfMonCtlHi4 : smnPerfMonCtrHi4;372		break;373	case 1:374		*lo_base_addr = is_ctrl ? smnPerfMonCtlLo5 : smnPerfMonCtrLo5;375		*hi_base_addr = is_ctrl ? smnPerfMonCtlHi5 : smnPerfMonCtrHi5;376		break;377	case 2:378		*lo_base_addr = is_ctrl ? smnPerfMonCtlLo6 : smnPerfMonCtrLo6;379		*hi_base_addr = is_ctrl ? smnPerfMonCtlHi6 : smnPerfMonCtrHi6;380		break;381	case 3:382		*lo_base_addr = is_ctrl ? smnPerfMonCtlLo7 : smnPerfMonCtrLo7;383		*hi_base_addr = is_ctrl ? smnPerfMonCtlHi7 : smnPerfMonCtrHi7;384		break;385 386	}387 388}389 390/* get read counter address */391static void df_v3_6_pmc_get_read_settings(struct amdgpu_device *adev,392					  uint64_t config,393					  int counter_idx,394					  uint32_t *lo_base_addr,395					  uint32_t *hi_base_addr)396{397	df_v3_6_pmc_get_addr(adev, config, counter_idx, 0, lo_base_addr,398								hi_base_addr);399}400 401/* get control counter settings i.e. address and values to set */402static int df_v3_6_pmc_get_ctrl_settings(struct amdgpu_device *adev,403					  uint64_t config,404					  int counter_idx,405					  uint32_t *lo_base_addr,406					  uint32_t *hi_base_addr,407					  uint32_t *lo_val,408					  uint32_t *hi_val,409					  bool is_enable)410{411 412	uint32_t eventsel, instance, unitmask;413	uint32_t instance_10, instance_5432, instance_76;414 415	df_v3_6_pmc_get_addr(adev, config, counter_idx, 1, lo_base_addr,416				hi_base_addr);417 418	if ((*lo_base_addr == 0) || (*hi_base_addr == 0)) {419		DRM_ERROR("[DF PMC] addressing not retrieved! Lo: %x, Hi: %x",420				*lo_base_addr, *hi_base_addr);421		return -ENXIO;422	}423 424	eventsel = DF_V3_6_GET_EVENT(config) & 0x3f;425	unitmask = DF_V3_6_GET_UNITMASK(config) & 0xf;426	instance = DF_V3_6_GET_INSTANCE(config);427 428	instance_10 = instance & 0x3;429	instance_5432 = (instance >> 2) & 0xf;430	instance_76 = (instance >> 6) & 0x3;431 432	*lo_val = (unitmask << 8) | (instance_10 << 6) | eventsel;433	*lo_val = is_enable ? *lo_val | (1 << 22) : *lo_val & ~(1 << 22);434	*hi_val = (instance_76 << 29) | instance_5432;435 436	DRM_DEBUG_DRIVER("config=%llx addr=%08x:%08x val=%08x:%08x",437		config, *lo_base_addr, *hi_base_addr, *lo_val, *hi_val);438 439	return 0;440}441 442/* add df performance counters for read */443static int df_v3_6_pmc_add_cntr(struct amdgpu_device *adev,444				   uint64_t config)445{446	int i;447 448	for (i = 0; i < DF_V3_6_MAX_COUNTERS; i++) {449		if (adev->df_perfmon_config_assign_mask[i] == 0U) {450			adev->df_perfmon_config_assign_mask[i] =451							config & 0x0FFFFFFUL;452			return i;453		}454	}455 456	return -ENOSPC;457}458 459#define DEFERRED_ARM_MASK	(1 << 31)460static int df_v3_6_pmc_set_deferred(struct amdgpu_device *adev,461				    uint64_t config, int counter_idx,462				    bool is_deferred)463{464 465	if (!df_v3_6_pmc_has_counter(adev, config, counter_idx))466		return -EINVAL;467 468	if (is_deferred)469		adev->df_perfmon_config_assign_mask[counter_idx] |=470							DEFERRED_ARM_MASK;471	else472		adev->df_perfmon_config_assign_mask[counter_idx] &=473							~DEFERRED_ARM_MASK;474 475	return 0;476}477 478static bool df_v3_6_pmc_is_deferred(struct amdgpu_device *adev,479				    uint64_t config,480				    int counter_idx)481{482	return	(df_v3_6_pmc_has_counter(adev, config, counter_idx) &&483			(adev->df_perfmon_config_assign_mask[counter_idx]484				& DEFERRED_ARM_MASK));485 486}487 488/* release performance counter */489static void df_v3_6_pmc_release_cntr(struct amdgpu_device *adev,490				     uint64_t config,491				     int counter_idx)492{493	if (df_v3_6_pmc_has_counter(adev, config, counter_idx))494		adev->df_perfmon_config_assign_mask[counter_idx] = 0ULL;495}496 497 498static void df_v3_6_reset_perfmon_cntr(struct amdgpu_device *adev,499					 uint64_t config,500					 int counter_idx)501{502	uint32_t lo_base_addr = 0, hi_base_addr = 0;503 504	df_v3_6_pmc_get_read_settings(adev, config, counter_idx, &lo_base_addr,505				      &hi_base_addr);506 507	if ((lo_base_addr == 0) || (hi_base_addr == 0))508		return;509 510	df_v3_6_perfmon_wreg(adev, lo_base_addr, 0, hi_base_addr, 0);511}512 513/* return available counter if is_add == 1 otherwise return error status. */514static int df_v3_6_pmc_start(struct amdgpu_device *adev, uint64_t config,515			     int counter_idx, int is_add)516{517	uint32_t lo_base_addr, hi_base_addr, lo_val, hi_val;518	int err = 0, ret = 0;519 520	switch (adev->asic_type) {521	case CHIP_VEGA20:522	case CHIP_ARCTURUS:523		if (is_add)524			return df_v3_6_pmc_add_cntr(adev, config);525 526		ret = df_v3_6_pmc_get_ctrl_settings(adev,527					config,528					counter_idx,529					&lo_base_addr,530					&hi_base_addr,531					&lo_val,532					&hi_val,533					true);534 535		if (ret)536			return ret;537 538		err = df_v3_6_perfmon_arm_with_retry(adev,539						     lo_base_addr,540						     lo_val,541						     hi_base_addr,542						     hi_val);543 544		if (err)545			ret = df_v3_6_pmc_set_deferred(adev, config,546							counter_idx, true);547 548		break;549	default:550		break;551	}552 553	return ret;554}555 556static int df_v3_6_pmc_stop(struct amdgpu_device *adev, uint64_t config,557			    int counter_idx, int is_remove)558{559	uint32_t lo_base_addr, hi_base_addr, lo_val, hi_val;560	int ret = 0;561 562	switch (adev->asic_type) {563	case CHIP_VEGA20:564	case CHIP_ARCTURUS:565		ret = df_v3_6_pmc_get_ctrl_settings(adev,566			config,567			counter_idx,568			&lo_base_addr,569			&hi_base_addr,570			&lo_val,571			&hi_val,572			false);573 574		if (ret)575			return ret;576 577		df_v3_6_perfmon_wreg(adev, lo_base_addr, lo_val,578							hi_base_addr, hi_val);579 580		if (is_remove) {581			df_v3_6_reset_perfmon_cntr(adev, config, counter_idx);582			df_v3_6_pmc_release_cntr(adev, config, counter_idx);583		}584 585		break;586	default:587		break;588	}589 590	return ret;591}592 593static void df_v3_6_pmc_get_count(struct amdgpu_device *adev,594				  uint64_t config,595				  int counter_idx,596				  uint64_t *count)597{598	uint32_t lo_base_addr = 0, hi_base_addr = 0, lo_val = 0, hi_val = 0;599	*count = 0;600 601	switch (adev->asic_type) {602	case CHIP_VEGA20:603	case CHIP_ARCTURUS:604		df_v3_6_pmc_get_read_settings(adev, config, counter_idx,605						&lo_base_addr, &hi_base_addr);606 607		if ((lo_base_addr == 0) || (hi_base_addr == 0))608			return;609 610		/* rearm the counter or throw away count value on failure */611		if (df_v3_6_pmc_is_deferred(adev, config, counter_idx)) {612			int rearm_err = df_v3_6_perfmon_arm_with_status(adev,613							lo_base_addr, lo_val,614							hi_base_addr, hi_val);615 616			if (rearm_err)617				return;618 619			df_v3_6_pmc_set_deferred(adev, config, counter_idx,620									false);621		}622 623		df_v3_6_perfmon_rreg(adev, lo_base_addr, &lo_val,624				hi_base_addr, &hi_val);625 626		*count  = ((hi_val | 0ULL) << 32) | (lo_val | 0ULL);627 628		if (*count >= DF_V3_6_PERFMON_OVERFLOW)629			*count = 0;630 631		DRM_DEBUG_DRIVER("config=%llx addr=%08x:%08x val=%08x:%08x",632			 config, lo_base_addr, hi_base_addr, lo_val, hi_val);633 634		break;635	default:636		break;637	}638}639 640static bool df_v3_6_query_ras_poison_mode(struct amdgpu_device *adev)641{642	uint32_t hw_assert_msklo, hw_assert_mskhi;643	uint32_t v0, v1, v28, v31;644 645	hw_assert_msklo = RREG32_SOC15(DF, 0,646				mmDF_CS_UMC_AON0_HardwareAssertMaskLow);647	hw_assert_mskhi = RREG32_SOC15(DF, 0,648				mmDF_NCS_PG0_HardwareAssertMaskHigh);649 650	v0 = REG_GET_FIELD(hw_assert_msklo,651		DF_CS_UMC_AON0_HardwareAssertMaskLow, HWAssertMsk0);652	v1 = REG_GET_FIELD(hw_assert_msklo,653		DF_CS_UMC_AON0_HardwareAssertMaskLow, HWAssertMsk1);654	v28 = REG_GET_FIELD(hw_assert_mskhi,655		DF_NCS_PG0_HardwareAssertMaskHigh, HWAssertMsk28);656	v31 = REG_GET_FIELD(hw_assert_mskhi,657		DF_NCS_PG0_HardwareAssertMaskHigh, HWAssertMsk31);658 659	if (v0 && v1 && v28 && v31)660		return true;661	else if (!v0 && !v1 && !v28 && !v31)662		return false;663	else {664		dev_warn(adev->dev, "DF poison setting is inconsistent(%d:%d:%d:%d)!\n",665				v0, v1, v28, v31);666		return false;667	}668}669 670const struct amdgpu_df_funcs df_v3_6_funcs = {671	.sw_init = df_v3_6_sw_init,672	.sw_fini = df_v3_6_sw_fini,673	.enable_broadcast_mode = df_v3_6_enable_broadcast_mode,674	.get_fb_channel_number = df_v3_6_get_fb_channel_number,675	.get_hbm_channel_number = df_v3_6_get_hbm_channel_number,676	.update_medium_grain_clock_gating =677			df_v3_6_update_medium_grain_clock_gating,678	.get_clockgating_state = df_v3_6_get_clockgating_state,679	.pmc_start = df_v3_6_pmc_start,680	.pmc_stop = df_v3_6_pmc_stop,681	.pmc_get_count = df_v3_6_pmc_get_count,682	.get_fica = df_v3_6_get_fica,683	.set_fica = df_v3_6_set_fica,684	.query_ras_poison_mode = df_v3_6_query_ras_poison_mode,685};686