diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
103 files changed, 2337 insertions, 654 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile index 2afecc55090f..260e32ef7bae 100644 --- a/drivers/gpu/drm/amd/amdgpu/Makefile +++ b/drivers/gpu/drm/amd/amdgpu/Makefile @@ -80,7 +80,7 @@ amdgpu-y += amdgpu_device.o amdgpu_doorbell_mgr.o amdgpu_kms.o \  	amdgpu_umc.o smu_v11_0_i2c.o amdgpu_fru_eeprom.o amdgpu_rap.o \  	amdgpu_fw_attestation.o amdgpu_securedisplay.o \  	amdgpu_eeprom.o amdgpu_mca.o amdgpu_psp_ta.o amdgpu_lsdma.o \ -	amdgpu_ring_mux.o amdgpu_xcp.o +	amdgpu_ring_mux.o amdgpu_xcp.o amdgpu_seq64.o  amdgpu-$(CONFIG_PROC_FS) += amdgpu_fdinfo.o diff --git a/drivers/gpu/drm/amd/amdgpu/aldebaran.c b/drivers/gpu/drm/amd/amdgpu/aldebaran.c index 02f4c6f9d4f6..576067d66bb9 100644 --- a/drivers/gpu/drm/amd/amdgpu/aldebaran.c +++ b/drivers/gpu/drm/amd/amdgpu/aldebaran.c @@ -330,6 +330,7 @@ aldebaran_mode2_restore_hwcontext(struct amdgpu_reset_control *reset_ctl,  {  	struct list_head *reset_device_list = reset_context->reset_device_list;  	struct amdgpu_device *tmp_adev = NULL; +	struct amdgpu_ras *con;  	int r;  	if (reset_device_list == NULL) @@ -355,7 +356,30 @@ aldebaran_mode2_restore_hwcontext(struct amdgpu_reset_control *reset_ctl,  		 */  		amdgpu_register_gpu_instance(tmp_adev); -		/* Resume RAS */ +		/* Resume RAS, ecc_irq */ +		con = amdgpu_ras_get_context(tmp_adev); +		if (!amdgpu_sriov_vf(tmp_adev) && con) { +			if (tmp_adev->sdma.ras && +				tmp_adev->sdma.ras->ras_block.ras_late_init) { +				r = tmp_adev->sdma.ras->ras_block.ras_late_init(tmp_adev, +						&tmp_adev->sdma.ras->ras_block.ras_comm); +				if (r) { +					dev_err(tmp_adev->dev, "SDMA failed to execute ras_late_init! ret:%d\n", r); +					goto end; +				} +			} + +			if (tmp_adev->gfx.ras && +				tmp_adev->gfx.ras->ras_block.ras_late_init) { +				r = tmp_adev->gfx.ras->ras_block.ras_late_init(tmp_adev, +						&tmp_adev->gfx.ras->ras_block.ras_comm); +				if (r) { +					dev_err(tmp_adev->dev, "GFX failed to execute ras_late_init! ret:%d\n", r); +					goto end; +				} +			} +		} +  		amdgpu_ras_resume(tmp_adev);  		/* Update PSP FW topology after reset */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 9d92ca157677..3d8a48f46b01 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -109,6 +109,8 @@  #include "amdgpu_mca.h"  #include "amdgpu_ras.h"  #include "amdgpu_xcp.h" +#include "amdgpu_seq64.h" +#include "amdgpu_reg_state.h"  #define MAX_GPU_INSTANCE		64 @@ -250,6 +252,8 @@ extern int amdgpu_seamless;  extern int amdgpu_user_partt_mode;  extern int amdgpu_agp; +extern int amdgpu_wbrf; +  #define AMDGPU_VM_MAX_NUM_CTX			4096  #define AMDGPU_SG_THRESHOLD			(256*1024*1024)  #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS	        3000 @@ -468,6 +472,7 @@ struct amdgpu_fpriv {  	struct amdgpu_vm	vm;  	struct amdgpu_bo_va	*prt_va;  	struct amdgpu_bo_va	*csa_va; +	struct amdgpu_bo_va	*seq64_va;  	struct mutex		bo_list_lock;  	struct idr		bo_list_handles;  	struct amdgpu_ctx_mgr	ctx_mgr; @@ -506,6 +511,31 @@ struct amdgpu_allowed_register_entry {  	bool grbm_indexed;  }; +/** + * enum amd_reset_method - Methods for resetting AMD GPU devices + * + * @AMD_RESET_METHOD_NONE: The device will not be reset. + * @AMD_RESET_LEGACY: Method reserved for SI, CIK and VI ASICs. + * @AMD_RESET_MODE0: Reset the entire ASIC. Not currently available for the + *                   any device. + * @AMD_RESET_MODE1: Resets all IP blocks on the ASIC (SDMA, GFX, VCN, etc.) + *                   individually. Suitable only for some discrete GPU, not + *                   available for all ASICs. + * @AMD_RESET_MODE2: Resets a lesser level of IPs compared to MODE1. Which IPs + *                   are reset depends on the ASIC. Notably doesn't reset IPs + *                   shared with the CPU on APUs or the memory controllers (so + *                   VRAM is not lost). Not available on all ASICs. + * @AMD_RESET_BACO: BACO (Bus Alive, Chip Off) method powers off and on the card + *                  but without powering off the PCI bus. Suitable only for + *                  discrete GPUs. + * @AMD_RESET_PCI: Does a full bus reset using core Linux subsystem PCI reset + *                 and does a secondary bus reset or FLR, depending on what the + *                 underlying hardware supports. + * + * Methods available for AMD GPU driver for resetting the device. Not all + * methods are suitable for every device. User can override the method using + * module parameter `reset_method`. + */  enum amd_reset_method {  	AMD_RESET_METHOD_NONE = -1,  	AMD_RESET_METHOD_LEGACY = 0, @@ -585,6 +615,10 @@ struct amdgpu_asic_funcs {  				  const struct amdgpu_video_codecs **codecs);  	/* encode "> 32bits" smn addressing */  	u64 (*encode_ext_smn_addressing)(int ext_id); + +	ssize_t (*get_reg_state)(struct amdgpu_device *adev, +				 enum amdgpu_reg_state reg_state, void *buf, +				 size_t max_size);  };  /* @@ -757,6 +791,7 @@ struct amdgpu_mqd_prop {  	uint64_t eop_gpu_addr;  	uint32_t hqd_pipe_priority;  	uint32_t hqd_queue_priority; +	bool allow_tunneling;  	bool hqd_active;  }; @@ -986,6 +1021,9 @@ struct amdgpu_device {  	/* GDS */  	struct amdgpu_gds		gds; +	/* for userq and VM fences */ +	struct amdgpu_seq64		seq64; +  	/* KFD */  	struct amdgpu_kfd_dev		kfd; @@ -1106,6 +1144,7 @@ struct amdgpu_device {  	bool                            debug_vm;  	bool                            debug_largebar;  	bool                            debug_disable_soft_recovery; +	bool                            debug_use_vram_fw_buf;  };  static inline uint32_t amdgpu_ip_version(const struct amdgpu_device *adev, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c index 75dc58470393..41db030ddc4e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c @@ -138,6 +138,30 @@ static void amdgpu_amdkfd_reset_work(struct work_struct *work)  	amdgpu_device_gpu_recover(adev, NULL, &reset_context);  } +static const struct drm_client_funcs kfd_client_funcs = { +	.unregister	= drm_client_release, +}; + +int amdgpu_amdkfd_drm_client_create(struct amdgpu_device *adev) +{ +	int ret; + +	if (!adev->kfd.init_complete) +		return 0; + +	ret = drm_client_init(&adev->ddev, &adev->kfd.client, "kfd", +			      &kfd_client_funcs); +	if (ret) { +		dev_err(adev->dev, "Failed to init DRM client: %d\n", +			ret); +		return ret; +	} + +	drm_client_register(&adev->kfd.client); + +	return 0; +} +  void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)  {  	int i; @@ -684,10 +708,8 @@ err:  void amdgpu_amdkfd_set_compute_idle(struct amdgpu_device *adev, bool idle)  {  	enum amd_powergating_state state = idle ? AMD_PG_STATE_GATE : AMD_PG_STATE_UNGATE; -	/* Temporary workaround to fix issues observed in some -	 * compute applications when GFXOFF is enabled on GFX11. -	 */ -	if (IP_VERSION_MAJ(amdgpu_ip_version(adev, GC_HWIP, 0)) == 11) { +	if (IP_VERSION_MAJ(amdgpu_ip_version(adev, GC_HWIP, 0)) == 11 && +	    ((adev->mes.kiq_version & AMDGPU_MES_VERSION_MASK) <= 64)) {  		pr_debug("GFXOFF is %s\n", idle ? "enabled" : "disabled");  		amdgpu_gfx_off_ctrl(adev, idle);  	} else if ((IP_VERSION_MAJ(amdgpu_ip_version(adev, GC_HWIP, 0)) == 9) && @@ -710,35 +732,6 @@ bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid)  	return false;  } -int amdgpu_amdkfd_flush_gpu_tlb_vmid(struct amdgpu_device *adev, -				     uint16_t vmid) -{ -	if (adev->family == AMDGPU_FAMILY_AI) { -		int i; - -		for_each_set_bit(i, adev->vmhubs_mask, AMDGPU_MAX_VMHUBS) -			amdgpu_gmc_flush_gpu_tlb(adev, vmid, i, 0); -	} else { -		amdgpu_gmc_flush_gpu_tlb(adev, vmid, AMDGPU_GFXHUB(0), 0); -	} - -	return 0; -} - -int amdgpu_amdkfd_flush_gpu_tlb_pasid(struct amdgpu_device *adev, -				      uint16_t pasid, -				      enum TLB_FLUSH_TYPE flush_type, -				      uint32_t inst) -{ -	bool all_hub = false; - -	if (adev->family == AMDGPU_FAMILY_AI || -	    adev->family == AMDGPU_FAMILY_RV) -		all_hub = true; - -	return amdgpu_gmc_flush_gpu_tlb_pasid(adev, pasid, flush_type, all_hub, inst); -} -  bool amdgpu_amdkfd_have_atomics_support(struct amdgpu_device *adev)  {  	return adev->have_atomics_support; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h index dac983da961d..27c61c535e29 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h @@ -33,6 +33,7 @@  #include <linux/mmu_notifier.h>  #include <linux/memremap.h>  #include <kgd_kfd_interface.h> +#include <drm/drm_client.h>  #include "amdgpu_sync.h"  #include "amdgpu_vm.h"  #include "amdgpu_xcp.h" @@ -83,6 +84,7 @@ struct kgd_mem {  	struct amdgpu_sync sync; +	uint32_t gem_handle;  	bool aql_queue;  	bool is_imported;  }; @@ -105,6 +107,9 @@ struct amdgpu_kfd_dev {  	/* HMM page migration MEMORY_DEVICE_PRIVATE mapping */  	struct dev_pagemap pgmap; + +	/* Client for KFD BO GEM handle allocations */ +	struct drm_client_dev client;  };  enum kgd_engine_type { @@ -162,11 +167,6 @@ int amdgpu_amdkfd_submit_ib(struct amdgpu_device *adev,  				uint32_t *ib_cmd, uint32_t ib_len);  void amdgpu_amdkfd_set_compute_idle(struct amdgpu_device *adev, bool idle);  bool amdgpu_amdkfd_have_atomics_support(struct amdgpu_device *adev); -int amdgpu_amdkfd_flush_gpu_tlb_vmid(struct amdgpu_device *adev, -				uint16_t vmid); -int amdgpu_amdkfd_flush_gpu_tlb_pasid(struct amdgpu_device *adev, -				uint16_t pasid, enum TLB_FLUSH_TYPE flush_type, -				uint32_t inst);  bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid); @@ -182,6 +182,8 @@ int amdgpu_queue_mask_bit_to_set_resource_bit(struct amdgpu_device *adev,  struct amdgpu_amdkfd_fence *amdgpu_amdkfd_fence_create(u64 context,  				struct mm_struct *mm,  				struct svm_range_bo *svm_bo); + +int amdgpu_amdkfd_drm_client_create(struct amdgpu_device *adev);  #if defined(CONFIG_DEBUG_FS)  int kfd_debugfs_kfd_mem_limits(struct seq_file *m, void *data);  #endif @@ -301,7 +303,7 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(struct amdgpu_device *adev,  					  struct kgd_mem *mem, void *drm_priv);  int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(  		struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv); -void amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv); +int amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv);  int amdgpu_amdkfd_gpuvm_sync_memory(  		struct amdgpu_device *adev, struct kgd_mem *mem, bool intr);  int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_mem *mem, @@ -311,14 +313,13 @@ void amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(struct kgd_mem *mem);  int amdgpu_amdkfd_map_gtt_bo_to_gart(struct amdgpu_device *adev, struct amdgpu_bo *bo);  int amdgpu_amdkfd_gpuvm_restore_process_bos(void *process_info, -					    struct dma_fence **ef); +					    struct dma_fence __rcu **ef);  int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct amdgpu_device *adev,  					      struct kfd_vm_fault_info *info); -int amdgpu_amdkfd_gpuvm_import_dmabuf(struct amdgpu_device *adev, -				      struct dma_buf *dmabuf, -				      uint64_t va, void *drm_priv, -				      struct kgd_mem **mem, uint64_t *size, -				      uint64_t *mmap_offset); +int amdgpu_amdkfd_gpuvm_import_dmabuf_fd(struct amdgpu_device *adev, int fd, +					 uint64_t va, void *drm_priv, +					 struct kgd_mem **mem, uint64_t *size, +					 uint64_t *mmap_offset);  int amdgpu_amdkfd_gpuvm_export_dmabuf(struct kgd_mem *mem,  				      struct dma_buf **dmabuf);  void amdgpu_amdkfd_debug_mem_fence(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c index 625db444df1c..3a3f3ce09f00 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c @@ -200,7 +200,7 @@ int kgd_arcturus_hqd_sdma_dump(struct amdgpu_device *adev,  #undef HQD_N_REGS  #define HQD_N_REGS (19+6+7+10) -	*dump = kmalloc_array(HQD_N_REGS * 2, sizeof(uint32_t), GFP_KERNEL); +	*dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL);  	if (*dump == NULL)  		return -ENOMEM; @@ -290,7 +290,7 @@ static int suspend_resume_compute_scheduler(struct amdgpu_device *adev, bool sus  	for (i = 0; i < adev->gfx.num_compute_rings; i++) {  		struct amdgpu_ring *ring = &adev->gfx.compute_ring[i]; -		if (!(ring && ring->sched.thread)) +		if (!amdgpu_ring_sched_ready(ring))  			continue;  		/* stop secheduler and drain ring. */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c index 469785d33791..1ef758ac5076 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c @@ -90,7 +90,7 @@ struct amdgpu_amdkfd_fence *to_amdgpu_amdkfd_fence(struct dma_fence *f)  		return NULL;  	fence = container_of(f, struct amdgpu_amdkfd_fence, base); -	if (fence && f->ops == &amdkfd_fence_ops) +	if (f->ops == &amdkfd_fence_ops)  		return fence;  	return NULL; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c index f6598b9e4faa..a5c7259cf2a3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c @@ -141,7 +141,7 @@ static int kgd_gfx_v9_4_3_hqd_sdma_dump(struct amdgpu_device *adev,  		(*dump)[i++][1] = RREG32(addr);         \  	} while (0) -	*dump = kmalloc_array(HQD_N_REGS * 2, sizeof(uint32_t), GFP_KERNEL); +	*dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL);  	if (*dump == NULL)  		return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c index 6bf448ab3dff..ca4a6b82817f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c @@ -214,7 +214,7 @@ static int kgd_hqd_dump(struct amdgpu_device *adev,  		(*dump)[i++][1] = RREG32(addr);		\  	} while (0) -	*dump = kmalloc_array(HQD_N_REGS * 2, sizeof(uint32_t), GFP_KERNEL); +	*dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL);  	if (*dump == NULL)  		return -ENOMEM; @@ -301,7 +301,7 @@ static int kgd_hqd_sdma_dump(struct amdgpu_device *adev,  #undef HQD_N_REGS  #define HQD_N_REGS (19+4) -	*dump = kmalloc_array(HQD_N_REGS * 2, sizeof(uint32_t), GFP_KERNEL); +	*dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL);  	if (*dump == NULL)  		return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c index cd06e4a6d1da..0f3e2944edd7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c @@ -238,7 +238,7 @@ static int kgd_hqd_dump(struct amdgpu_device *adev,  		(*dump)[i++][1] = RREG32(addr);		\  	} while (0) -	*dump = kmalloc_array(HQD_N_REGS * 2, sizeof(uint32_t), GFP_KERNEL); +	*dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL);  	if (*dump == NULL)  		return -ENOMEM; @@ -324,7 +324,7 @@ static int kgd_hqd_sdma_dump(struct amdgpu_device *adev,  #undef HQD_N_REGS  #define HQD_N_REGS (19+4+2+3+7) -	*dump = kmalloc_array(HQD_N_REGS * 2, sizeof(uint32_t), GFP_KERNEL); +	*dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL);  	if (*dump == NULL)  		return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c index 00fbc0f44c92..5a35a8ca8922 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c @@ -363,7 +363,7 @@ int kgd_gfx_v9_hqd_dump(struct amdgpu_device *adev,  		(*dump)[i++][1] = RREG32(addr);		\  	} while (0) -	*dump = kmalloc_array(HQD_N_REGS * 2, sizeof(uint32_t), GFP_KERNEL); +	*dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL);  	if (*dump == NULL)  		return -ENOMEM; @@ -460,7 +460,7 @@ static int kgd_hqd_sdma_dump(struct amdgpu_device *adev,  #undef HQD_N_REGS  #define HQD_N_REGS (19+6+7+10) -	*dump = kmalloc_array(HQD_N_REGS * 2, sizeof(uint32_t), GFP_KERNEL); +	*dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL);  	if (*dump == NULL)  		return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index 41fbc4fd0fac..231fd927dcfb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -25,6 +25,7 @@  #include <linux/pagemap.h>  #include <linux/sched/mm.h>  #include <linux/sched/task.h> +#include <linux/fdtable.h>  #include <drm/ttm/ttm_tt.h>  #include <drm/drm_exec.h> @@ -806,13 +807,22 @@ kfd_mem_dmaunmap_attachment(struct kgd_mem *mem,  static int kfd_mem_export_dmabuf(struct kgd_mem *mem)  {  	if (!mem->dmabuf) { -		struct dma_buf *ret = amdgpu_gem_prime_export( -			&mem->bo->tbo.base, +		struct amdgpu_device *bo_adev; +		struct dma_buf *dmabuf; +		int r, fd; + +		bo_adev = amdgpu_ttm_adev(mem->bo->tbo.bdev); +		r = drm_gem_prime_handle_to_fd(&bo_adev->ddev, bo_adev->kfd.client.file, +					       mem->gem_handle,  			mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE ? -				DRM_RDWR : 0); -		if (IS_ERR(ret)) -			return PTR_ERR(ret); -		mem->dmabuf = ret; +					       DRM_RDWR : 0, &fd); +		if (r) +			return r; +		dmabuf = dma_buf_get(fd); +		close_fd(fd); +		if (WARN_ON_ONCE(IS_ERR(dmabuf))) +			return PTR_ERR(dmabuf); +		mem->dmabuf = dmabuf;  	}  	return 0; @@ -1137,7 +1147,7 @@ static int reserve_bo_and_vm(struct kgd_mem *mem,  	ctx->n_vms = 1;  	ctx->sync = &mem->sync; -	drm_exec_init(&ctx->exec, DRM_EXEC_INTERRUPTIBLE_WAIT); +	drm_exec_init(&ctx->exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);  	drm_exec_until_all_locked(&ctx->exec) {  		ret = amdgpu_vm_lock_pd(vm, &ctx->exec, 2);  		drm_exec_retry_on_contention(&ctx->exec); @@ -1176,7 +1186,7 @@ static int reserve_bo_and_cond_vms(struct kgd_mem *mem,  	int ret;  	ctx->sync = &mem->sync; -	drm_exec_init(&ctx->exec, DRM_EXEC_INTERRUPTIBLE_WAIT); +	drm_exec_init(&ctx->exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);  	drm_exec_until_all_locked(&ctx->exec) {  		ctx->n_vms = 0;  		list_for_each_entry(entry, &mem->attachments, list) { @@ -1384,7 +1394,6 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info,  				  amdgpu_amdkfd_restore_userptr_worker);  		*process_info = info; -		*ef = dma_fence_get(&info->eviction_fence->base);  	}  	vm->process_info = *process_info; @@ -1415,6 +1424,8 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info,  	list_add_tail(&vm->vm_list_node,  			&(vm->process_info->vm_list_head));  	vm->process_info->n_vms++; + +	*ef = dma_fence_get(&vm->process_info->eviction_fence->base);  	mutex_unlock(&vm->process_info->lock);  	return 0; @@ -1426,10 +1437,7 @@ validate_pd_fail:  reserve_pd_fail:  	vm->process_info = NULL;  	if (info) { -		/* Two fence references: one in info and one in *ef */  		dma_fence_put(&info->eviction_fence->base); -		dma_fence_put(*ef); -		*ef = NULL;  		*process_info = NULL;  		put_pid(info->pid);  create_evict_fence_fail: @@ -1623,7 +1631,8 @@ int amdgpu_amdkfd_criu_resume(void *p)  		goto out_unlock;  	}  	WRITE_ONCE(pinfo->block_mmu_notifications, false); -	schedule_delayed_work(&pinfo->restore_userptr_work, 0); +	queue_delayed_work(system_freezable_wq, +			   &pinfo->restore_userptr_work, 0);  out_unlock:  	mutex_unlock(&pinfo->lock); @@ -1779,6 +1788,9 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(  		pr_debug("Failed to allow vma node access. ret %d\n", ret);  		goto err_node_allow;  	} +	ret = drm_gem_handle_create(adev->kfd.client.file, gobj, &(*mem)->gem_handle); +	if (ret) +		goto err_gem_handle_create;  	bo = gem_to_amdgpu_bo(gobj);  	if (bo_type == ttm_bo_type_sg) {  		bo->tbo.sg = sg; @@ -1830,6 +1842,8 @@ allocate_init_user_pages_failed:  err_pin_bo:  err_validate_bo:  	remove_kgd_mem_from_kfd_bo_list(*mem, avm->process_info); +	drm_gem_handle_delete(adev->kfd.client.file, (*mem)->gem_handle); +err_gem_handle_create:  	drm_vma_node_revoke(&gobj->vma_node, drm_priv);  err_node_allow:  	/* Don't unreserve system mem limit twice */ @@ -1942,8 +1956,11 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(  	/* Free the BO*/  	drm_vma_node_revoke(&mem->bo->tbo.base.vma_node, drm_priv); -	if (mem->dmabuf) +	drm_gem_handle_delete(adev->kfd.client.file, mem->gem_handle); +	if (mem->dmabuf) {  		dma_buf_put(mem->dmabuf); +		mem->dmabuf = NULL; +	}  	mutex_destroy(&mem->lock);  	/* If this releases the last reference, it will end up calling @@ -2068,21 +2085,35 @@ out:  	return ret;  } -void amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv) +int amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv)  {  	struct kfd_mem_attachment *entry;  	struct amdgpu_vm *vm; +	int ret;  	vm = drm_priv_to_vm(drm_priv);  	mutex_lock(&mem->lock); +	ret = amdgpu_bo_reserve(mem->bo, true); +	if (ret) +		goto out; +  	list_for_each_entry(entry, &mem->attachments, list) { -		if (entry->bo_va->base.vm == vm) -			kfd_mem_dmaunmap_attachment(mem, entry); +		if (entry->bo_va->base.vm != vm) +			continue; +		if (entry->bo_va->base.bo->tbo.ttm && +		    !entry->bo_va->base.bo->tbo.ttm->sg) +			continue; + +		kfd_mem_dmaunmap_attachment(mem, entry);  	} +	amdgpu_bo_unreserve(mem->bo); +out:  	mutex_unlock(&mem->lock); + +	return ret;  }  int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu( @@ -2295,34 +2326,26 @@ int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct amdgpu_device *adev,  	return 0;  } -int amdgpu_amdkfd_gpuvm_import_dmabuf(struct amdgpu_device *adev, -				      struct dma_buf *dma_buf, -				      uint64_t va, void *drm_priv, -				      struct kgd_mem **mem, uint64_t *size, -				      uint64_t *mmap_offset) +static int import_obj_create(struct amdgpu_device *adev, +			     struct dma_buf *dma_buf, +			     struct drm_gem_object *obj, +			     uint64_t va, void *drm_priv, +			     struct kgd_mem **mem, uint64_t *size, +			     uint64_t *mmap_offset)  {  	struct amdgpu_vm *avm = drm_priv_to_vm(drm_priv); -	struct drm_gem_object *obj;  	struct amdgpu_bo *bo;  	int ret; -	obj = amdgpu_gem_prime_import(adev_to_drm(adev), dma_buf); -	if (IS_ERR(obj)) -		return PTR_ERR(obj); -  	bo = gem_to_amdgpu_bo(obj);  	if (!(bo->preferred_domains & (AMDGPU_GEM_DOMAIN_VRAM | -				    AMDGPU_GEM_DOMAIN_GTT))) { +				    AMDGPU_GEM_DOMAIN_GTT)))  		/* Only VRAM and GTT BOs are supported */ -		ret = -EINVAL; -		goto err_put_obj; -	} +		return -EINVAL;  	*mem = kzalloc(sizeof(struct kgd_mem), GFP_KERNEL); -	if (!*mem) { -		ret = -ENOMEM; -		goto err_put_obj; -	} +	if (!*mem) +		return -ENOMEM;  	ret = drm_vma_node_allow(&obj->vma_node, drm_priv);  	if (ret) @@ -2372,8 +2395,41 @@ err_remove_mem:  	drm_vma_node_revoke(&obj->vma_node, drm_priv);  err_free_mem:  	kfree(*mem); +	return ret; +} + +int amdgpu_amdkfd_gpuvm_import_dmabuf_fd(struct amdgpu_device *adev, int fd, +					 uint64_t va, void *drm_priv, +					 struct kgd_mem **mem, uint64_t *size, +					 uint64_t *mmap_offset) +{ +	struct drm_gem_object *obj; +	uint32_t handle; +	int ret; + +	ret = drm_gem_prime_fd_to_handle(&adev->ddev, adev->kfd.client.file, fd, +					 &handle); +	if (ret) +		return ret; +	obj = drm_gem_object_lookup(adev->kfd.client.file, handle); +	if (!obj) { +		ret = -EINVAL; +		goto err_release_handle; +	} + +	ret = import_obj_create(adev, obj->dma_buf, obj, va, drm_priv, mem, size, +				mmap_offset); +	if (ret) +		goto err_put_obj; + +	(*mem)->gem_handle = handle; + +	return 0; +  err_put_obj:  	drm_gem_object_put(obj); +err_release_handle: +	drm_gem_handle_delete(adev->kfd.client.file, handle);  	return ret;  } @@ -2426,7 +2482,8 @@ int amdgpu_amdkfd_evict_userptr(struct mmu_interval_notifier *mni,  				       KFD_QUEUE_EVICTION_TRIGGER_USERPTR);  		if (r)  			pr_err("Failed to quiesce KFD\n"); -		schedule_delayed_work(&process_info->restore_userptr_work, +		queue_delayed_work(system_freezable_wq, +			&process_info->restore_userptr_work,  			msecs_to_jiffies(AMDGPU_USERPTR_RESTORE_DELAY_MS));  	}  	mutex_unlock(&process_info->notifier_lock); @@ -2552,7 +2609,7 @@ static int validate_invalid_user_pages(struct amdkfd_process_info *process_info)  	amdgpu_sync_create(&sync); -	drm_exec_init(&exec, 0); +	drm_exec_init(&exec, 0, 0);  	/* Reserve all BOs and page tables for validation */  	drm_exec_until_all_locked(&exec) {  		/* Reserve all the page directories */ @@ -2749,7 +2806,8 @@ unlock_out:  	/* If validation failed, reschedule another attempt */  	if (evicted_bos) { -		schedule_delayed_work(&process_info->restore_userptr_work, +		queue_delayed_work(system_freezable_wq, +			&process_info->restore_userptr_work,  			msecs_to_jiffies(AMDGPU_USERPTR_RESTORE_DELAY_MS));  		kfd_smi_event_queue_restore_rescheduled(mm); @@ -2758,6 +2816,23 @@ unlock_out:  	put_task_struct(usertask);  } +static void replace_eviction_fence(struct dma_fence __rcu **ef, +				   struct dma_fence *new_ef) +{ +	struct dma_fence *old_ef = rcu_replace_pointer(*ef, new_ef, true +		/* protected by process_info->lock */); + +	/* If we're replacing an unsignaled eviction fence, that fence will +	 * never be signaled, and if anyone is still waiting on that fence, +	 * they will hang forever. This should never happen. We should only +	 * replace the fence in restore_work that only gets scheduled after +	 * eviction work signaled the fence. +	 */ +	WARN_ONCE(!dma_fence_is_signaled(old_ef), +		  "Replacing unsignaled eviction fence"); +	dma_fence_put(old_ef); +} +  /** amdgpu_amdkfd_gpuvm_restore_process_bos - Restore all BOs for the given   *   KFD process identified by process_info   * @@ -2776,12 +2851,11 @@ unlock_out:   * 7.  Add fence to all PD and PT BOs.   * 8.  Unreserve all BOs   */ -int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence **ef) +int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence __rcu **ef)  {  	struct amdkfd_process_info *process_info = info;  	struct amdgpu_vm *peer_vm;  	struct kgd_mem *mem; -	struct amdgpu_amdkfd_fence *new_fence;  	struct list_head duplicate_save;  	struct amdgpu_sync sync_obj;  	unsigned long failed_size = 0; @@ -2793,7 +2867,7 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence **ef)  	mutex_lock(&process_info->lock); -	drm_exec_init(&exec, 0); +	drm_exec_init(&exec, 0, 0);  	drm_exec_until_all_locked(&exec) {  		list_for_each_entry(peer_vm, &process_info->vm_list_head,  				    vm_list_node) { @@ -2825,12 +2899,6 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence **ef)  	if (ret)  		goto validate_map_fail; -	ret = process_sync_pds_resv(process_info, &sync_obj); -	if (ret) { -		pr_debug("Memory eviction: Failed to sync to PD BO moving fence. Try again\n"); -		goto validate_map_fail; -	} -  	/* Validate BOs and map them to GPUVM (update VM page tables). */  	list_for_each_entry(mem, &process_info->kfd_bo_list,  			    validate_list) { @@ -2881,6 +2949,19 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence **ef)  	if (failed_size)  		pr_debug("0x%lx/0x%lx in system\n", failed_size, total_size); +	/* Update mappings not managed by KFD */ +	list_for_each_entry(peer_vm, &process_info->vm_list_head, +			vm_list_node) { +		struct amdgpu_device *adev = amdgpu_ttm_adev( +			peer_vm->root.bo->tbo.bdev); + +		ret = amdgpu_vm_handle_moved(adev, peer_vm, &exec.ticket); +		if (ret) { +			pr_debug("Memory eviction: handle moved failed. Try again\n"); +			goto validate_map_fail; +		} +	} +  	/* Update page directories */  	ret = process_update_pds(process_info, &sync_obj);  	if (ret) { @@ -2888,25 +2969,47 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence **ef)  		goto validate_map_fail;  	} +	/* Sync with fences on all the page tables. They implicitly depend on any +	 * move fences from amdgpu_vm_handle_moved above. +	 */ +	ret = process_sync_pds_resv(process_info, &sync_obj); +	if (ret) { +		pr_debug("Memory eviction: Failed to sync to PD BO moving fence. Try again\n"); +		goto validate_map_fail; +	} +  	/* Wait for validate and PT updates to finish */  	amdgpu_sync_wait(&sync_obj, false); -	/* Release old eviction fence and create new one, because fence only -	 * goes from unsignaled to signaled, fence cannot be reused. -	 * Use context and mm from the old fence. +	/* The old eviction fence may be unsignaled if restore happens +	 * after a GPU reset or suspend/resume. Keep the old fence in that +	 * case. Otherwise release the old eviction fence and create new +	 * one, because fence only goes from unsignaled to signaled once +	 * and cannot be reused. Use context and mm from the old fence. +	 * +	 * If an old eviction fence signals after this check, that's OK. +	 * Anyone signaling an eviction fence must stop the queues first +	 * and schedule another restore worker.  	 */ -	new_fence = amdgpu_amdkfd_fence_create( +	if (dma_fence_is_signaled(&process_info->eviction_fence->base)) { +		struct amdgpu_amdkfd_fence *new_fence = +			amdgpu_amdkfd_fence_create(  				process_info->eviction_fence->base.context,  				process_info->eviction_fence->mm,  				NULL); -	if (!new_fence) { -		pr_err("Failed to create eviction fence\n"); -		ret = -ENOMEM; -		goto validate_map_fail; + +		if (!new_fence) { +			pr_err("Failed to create eviction fence\n"); +			ret = -ENOMEM; +			goto validate_map_fail; +		} +		dma_fence_put(&process_info->eviction_fence->base); +		process_info->eviction_fence = new_fence; +		replace_eviction_fence(ef, dma_fence_get(&new_fence->base)); +	} else { +		WARN_ONCE(*ef != &process_info->eviction_fence->base, +			  "KFD eviction fence doesn't match KGD process_info");  	} -	dma_fence_put(&process_info->eviction_fence->base); -	process_info->eviction_fence = new_fence; -	*ef = dma_fence_get(&new_fence->base);  	/* Attach new eviction fence to all BOs except pinned ones */  	list_for_each_entry(mem, &process_info->kfd_bo_list, validate_list) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c index 7473a42f7d45..9caba10315a8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c @@ -103,7 +103,7 @@ int amdgpu_connector_get_monitor_bpc(struct drm_connector *connector)  	struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);  	struct amdgpu_connector_atom_dig *dig_connector;  	int bpc = 8; -	unsigned mode_clock, max_tmds_clock; +	unsigned int mode_clock, max_tmds_clock;  	switch (connector->connector_type) {  	case DRM_MODE_CONNECTOR_DVII: @@ -255,6 +255,7 @@ struct edid *amdgpu_connector_edid(struct drm_connector *connector)  		return amdgpu_connector->edid;  	} else if (edid_blob) {  		struct edid *edid = kmemdup(edid_blob->data, edid_blob->length, GFP_KERNEL); +  		if (edid)  			amdgpu_connector->edid = edid;  	} @@ -581,6 +582,7 @@ static int amdgpu_connector_set_property(struct drm_connector *connector,  			amdgpu_encoder = to_amdgpu_encoder(connector->encoder);  		} else {  			const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; +  			amdgpu_encoder = to_amdgpu_encoder(connector_funcs->best_encoder(connector));  		} @@ -797,6 +799,7 @@ static int amdgpu_connector_set_lcd_property(struct drm_connector *connector,  		amdgpu_encoder = to_amdgpu_encoder(connector->encoder);  	else {  		const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; +  		amdgpu_encoder = to_amdgpu_encoder(connector_funcs->best_encoder(connector));  	} @@ -979,6 +982,41 @@ amdgpu_connector_check_hpd_status_unchanged(struct drm_connector *connector)  	return false;  } +static void amdgpu_connector_shared_ddc(enum drm_connector_status *status, +					struct drm_connector *connector, +					struct amdgpu_connector *amdgpu_connector) +{ +	struct drm_connector *list_connector; +	struct drm_connector_list_iter iter; +	struct amdgpu_connector *list_amdgpu_connector; +	struct drm_device *dev = connector->dev; +	struct amdgpu_device *adev = drm_to_adev(dev); + +	if (amdgpu_connector->shared_ddc && *status == connector_status_connected) { +		drm_connector_list_iter_begin(dev, &iter); +		drm_for_each_connector_iter(list_connector, +					    &iter) { +			if (connector == list_connector) +				continue; +			list_amdgpu_connector = to_amdgpu_connector(list_connector); +			if (list_amdgpu_connector->shared_ddc && +			    list_amdgpu_connector->ddc_bus->rec.i2c_id == +			     amdgpu_connector->ddc_bus->rec.i2c_id) { +				/* cases where both connectors are digital */ +				if (list_connector->connector_type != DRM_MODE_CONNECTOR_VGA) { +					/* hpd is our only option in this case */ +					if (!amdgpu_display_hpd_sense(adev, +								      amdgpu_connector->hpd.hpd)) { +						amdgpu_connector_free_edid(connector); +						*status = connector_status_disconnected; +					} +				} +			} +		} +		drm_connector_list_iter_end(&iter); +	} +} +  /*   * DVI is complicated   * Do a DDC probe, if DDC probe passes, get the full EDID so @@ -1065,32 +1103,7 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)  			 * DDC line.  The latter is more complex because with DVI<->HDMI adapters  			 * you don't really know what's connected to which port as both are digital.  			 */ -			if (amdgpu_connector->shared_ddc && (ret == connector_status_connected)) { -				struct drm_connector *list_connector; -				struct drm_connector_list_iter iter; -				struct amdgpu_connector *list_amdgpu_connector; - -				drm_connector_list_iter_begin(dev, &iter); -				drm_for_each_connector_iter(list_connector, -							    &iter) { -					if (connector == list_connector) -						continue; -					list_amdgpu_connector = to_amdgpu_connector(list_connector); -					if (list_amdgpu_connector->shared_ddc && -					    (list_amdgpu_connector->ddc_bus->rec.i2c_id == -					     amdgpu_connector->ddc_bus->rec.i2c_id)) { -						/* cases where both connectors are digital */ -						if (list_connector->connector_type != DRM_MODE_CONNECTOR_VGA) { -							/* hpd is our only option in this case */ -							if (!amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd)) { -								amdgpu_connector_free_edid(connector); -								ret = connector_status_disconnected; -							} -						} -					} -				} -				drm_connector_list_iter_end(&iter); -			} +			amdgpu_connector_shared_ddc(&ret, connector, amdgpu_connector);  		}  	} @@ -1192,6 +1205,7 @@ amdgpu_connector_dvi_encoder(struct drm_connector *connector)  static void amdgpu_connector_dvi_force(struct drm_connector *connector)  {  	struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); +  	if (connector->force == DRM_FORCE_ON)  		amdgpu_connector->use_digital = false;  	if (connector->force == DRM_FORCE_ON_DIGITAL) @@ -1426,6 +1440,7 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force)  				ret = connector_status_connected;  			else if (amdgpu_connector->dac_load_detect) { /* try load detection */  				const struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; +  				ret = encoder_funcs->detect(encoder, connector);  			}  		} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index e50be6500030..6adeddfb3d56 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -66,7 +66,7 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p,  	amdgpu_sync_create(&p->sync);  	drm_exec_init(&p->exec, DRM_EXEC_INTERRUPTIBLE_WAIT | -		      DRM_EXEC_IGNORE_DUPLICATES); +		      DRM_EXEC_IGNORE_DUPLICATES, 0);  	return 0;  } @@ -870,9 +870,9 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,  		struct amdgpu_bo *bo = e->bo;  		int i; -		e->user_pages = kvmalloc_array(bo->tbo.ttm->num_pages, -					sizeof(struct page *), -					GFP_KERNEL | __GFP_ZERO); +		e->user_pages = kvcalloc(bo->tbo.ttm->num_pages, +					 sizeof(struct page *), +					 GFP_KERNEL);  		if (!e->user_pages) {  			DRM_ERROR("kvmalloc_array failure\n");  			r = -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c index 720011019741..796fa6f1420b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c @@ -70,7 +70,7 @@ int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,  	struct drm_exec exec;  	int r; -	drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT); +	drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);  	drm_exec_until_all_locked(&exec) {  		r = amdgpu_vm_lock_pd(vm, &exec, 0);  		if (likely(!r)) @@ -110,7 +110,7 @@ int amdgpu_unmap_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,  	struct drm_exec exec;  	int r; -	drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT); +	drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);  	drm_exec_until_all_locked(&exec) {  		r = amdgpu_vm_lock_pd(vm, &exec, 0);  		if (likely(!r)) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index e2ae9ba147ba..5cb33ac99f70 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -73,10 +73,10 @@ amdgpu_ctx_to_drm_sched_prio(int32_t ctx_prio)  		return DRM_SCHED_PRIORITY_NORMAL;  	case AMDGPU_CTX_PRIORITY_VERY_LOW: -		return DRM_SCHED_PRIORITY_MIN; +		return DRM_SCHED_PRIORITY_LOW;  	case AMDGPU_CTX_PRIORITY_LOW: -		return DRM_SCHED_PRIORITY_MIN; +		return DRM_SCHED_PRIORITY_LOW;  	case AMDGPU_CTX_PRIORITY_NORMAL:  		return DRM_SCHED_PRIORITY_NORMAL; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c index 0e61ebdb3f3e..1afbb2e932c6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c @@ -540,7 +540,11 @@ static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf,  	while (size) {  		uint32_t value; -		value = RREG32_PCIE(*pos); +		if (upper_32_bits(*pos)) +			value = RREG32_PCIE_EXT(*pos); +		else +			value = RREG32_PCIE(*pos); +  		r = put_user(value, (uint32_t *)buf);  		if (r)  			goto out; @@ -600,7 +604,10 @@ static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user  		if (r)  			goto out; -		WREG32_PCIE(*pos, value); +		if (upper_32_bits(*pos)) +			WREG32_PCIE_EXT(*pos, value); +		else +			WREG32_PCIE(*pos, value);  		result += 4;  		buf += 4; @@ -755,7 +762,7 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf,  	int r;  	if (!adev->smc_rreg) -		return -EPERM; +		return -EOPNOTSUPP;  	if (size & 0x3 || *pos & 0x3)  		return -EINVAL; @@ -814,7 +821,7 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *  	int r;  	if (!adev->smc_wreg) -		return -EPERM; +		return -EOPNOTSUPP;  	if (size & 0x3 || *pos & 0x3)  		return -EINVAL; @@ -1671,9 +1678,9 @@ static int amdgpu_debugfs_test_ib_show(struct seq_file *m, void *unused)  	for (i = 0; i < AMDGPU_MAX_RINGS; i++) {  		struct amdgpu_ring *ring = adev->rings[i]; -		if (!ring || !ring->sched.thread) +		if (!amdgpu_ring_sched_ready(ring))  			continue; -		kthread_park(ring->sched.thread); +		drm_sched_wqueue_stop(&ring->sched);  	}  	seq_puts(m, "run ib test:\n"); @@ -1687,9 +1694,9 @@ static int amdgpu_debugfs_test_ib_show(struct seq_file *m, void *unused)  	for (i = 0; i < AMDGPU_MAX_RINGS; i++) {  		struct amdgpu_ring *ring = adev->rings[i]; -		if (!ring || !ring->sched.thread) +		if (!amdgpu_ring_sched_ready(ring))  			continue; -		kthread_unpark(ring->sched.thread); +		drm_sched_wqueue_start(&ring->sched);  	}  	up_write(&adev->reset_domain->sem); @@ -1909,7 +1916,8 @@ static int amdgpu_debugfs_ib_preempt(void *data, u64 val)  	ring = adev->rings[val]; -	if (!ring || !ring->funcs->preempt_ib || !ring->sched.thread) +	if (!amdgpu_ring_sched_ready(ring) || +	    !ring->funcs->preempt_ib)  		return -EINVAL;  	/* the last preemption failed */ @@ -1927,7 +1935,7 @@ static int amdgpu_debugfs_ib_preempt(void *data, u64 val)  		goto pro_end;  	/* stop the scheduler */ -	kthread_park(ring->sched.thread); +	drm_sched_wqueue_stop(&ring->sched);  	/* preempt the IB */  	r = amdgpu_ring_preempt_ib(ring); @@ -1961,7 +1969,7 @@ static int amdgpu_debugfs_ib_preempt(void *data, u64 val)  failure:  	/* restart the scheduler */ -	kthread_unpark(ring->sched.thread); +	drm_sched_wqueue_start(&ring->sched);  	up_read(&adev->reset_domain->sem); @@ -2146,6 +2154,8 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)  	amdgpu_debugfs_firmware_init(adev);  	amdgpu_ta_if_debugfs_init(adev); +	amdgpu_debugfs_mes_event_log_init(adev); +  #if defined(CONFIG_DRM_AMD_DC)  	if (adev->dc_enabled)  		dtn_debugfs_init(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.h index 371a6f0deb29..0425432d8659 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.h @@ -32,3 +32,5 @@ void amdgpu_debugfs_fini(struct amdgpu_device *adev);  void amdgpu_debugfs_fence_init(struct amdgpu_device *adev);  void amdgpu_debugfs_firmware_init(struct amdgpu_device *adev);  void amdgpu_debugfs_gem_init(struct amdgpu_device *adev); +void amdgpu_debugfs_mes_event_log_init(struct amdgpu_device *adev); + diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 93cf73d6fa11..fdde7488d0ed 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -162,6 +162,65 @@ static ssize_t amdgpu_device_get_pcie_replay_count(struct device *dev,  static DEVICE_ATTR(pcie_replay_count, 0444,  		amdgpu_device_get_pcie_replay_count, NULL); +static ssize_t amdgpu_sysfs_reg_state_get(struct file *f, struct kobject *kobj, +					  struct bin_attribute *attr, char *buf, +					  loff_t ppos, size_t count) +{ +	struct device *dev = kobj_to_dev(kobj); +	struct drm_device *ddev = dev_get_drvdata(dev); +	struct amdgpu_device *adev = drm_to_adev(ddev); +	ssize_t bytes_read; + +	switch (ppos) { +	case AMDGPU_SYS_REG_STATE_XGMI: +		bytes_read = amdgpu_asic_get_reg_state( +			adev, AMDGPU_REG_STATE_TYPE_XGMI, buf, count); +		break; +	case AMDGPU_SYS_REG_STATE_WAFL: +		bytes_read = amdgpu_asic_get_reg_state( +			adev, AMDGPU_REG_STATE_TYPE_WAFL, buf, count); +		break; +	case AMDGPU_SYS_REG_STATE_PCIE: +		bytes_read = amdgpu_asic_get_reg_state( +			adev, AMDGPU_REG_STATE_TYPE_PCIE, buf, count); +		break; +	case AMDGPU_SYS_REG_STATE_USR: +		bytes_read = amdgpu_asic_get_reg_state( +			adev, AMDGPU_REG_STATE_TYPE_USR, buf, count); +		break; +	case AMDGPU_SYS_REG_STATE_USR_1: +		bytes_read = amdgpu_asic_get_reg_state( +			adev, AMDGPU_REG_STATE_TYPE_USR_1, buf, count); +		break; +	default: +		return -EINVAL; +	} + +	return bytes_read; +} + +BIN_ATTR(reg_state, 0444, amdgpu_sysfs_reg_state_get, NULL, +	 AMDGPU_SYS_REG_STATE_END); + +int amdgpu_reg_state_sysfs_init(struct amdgpu_device *adev) +{ +	int ret; + +	if (!amdgpu_asic_get_reg_state_supported(adev)) +		return 0; + +	ret = sysfs_create_bin_file(&adev->dev->kobj, &bin_attr_reg_state); + +	return ret; +} + +void amdgpu_reg_state_sysfs_fini(struct amdgpu_device *adev) +{ +	if (!amdgpu_asic_get_reg_state_supported(adev)) +		return; +	sysfs_remove_bin_file(&adev->dev->kobj, &bin_attr_reg_state); +} +  /**   * DOC: board_info   * @@ -1485,6 +1544,7 @@ bool amdgpu_device_need_post(struct amdgpu_device *adev)  				return true;  			fw_ver = *((uint32_t *)adev->pm.fw->data + 69); +			release_firmware(adev->pm.fw);  			if (fw_ver < 0x00160e00)  				return true;  		} @@ -1540,7 +1600,7 @@ bool amdgpu_device_seamless_boot_supported(struct amdgpu_device *adev)  	if (adev->mman.keep_stolen_vga_memory)  		return false; -	return adev->ip_versions[DCE_HWIP][0] >= IP_VERSION(3, 0, 0); +	return amdgpu_ip_version(adev, DCE_HWIP, 0) >= IP_VERSION(3, 0, 0);  }  /* @@ -1551,11 +1611,15 @@ bool amdgpu_device_seamless_boot_supported(struct amdgpu_device *adev)   * https://edc.intel.com/content/www/us/en/design/products/platforms/details/raptor-lake-s/13th-generation-core-processors-datasheet-volume-1-of-2/005/pci-express-support/   * https://gitlab.freedesktop.org/drm/amd/-/issues/2663   */ -static bool amdgpu_device_pcie_dynamic_switching_supported(void) +static bool amdgpu_device_pcie_dynamic_switching_supported(struct amdgpu_device *adev)  {  #if IS_ENABLED(CONFIG_X86)  	struct cpuinfo_x86 *c = &cpu_data(0); +	/* eGPU change speeds based on USB4 fabric conditions */ +	if (dev_is_removable(adev->dev)) +		return true; +  	if (c->x86_vendor == X86_VENDOR_INTEL)  		return false;  #endif @@ -2388,7 +2452,7 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)  		adev->pm.pp_feature &= ~PP_GFXOFF_MASK;  	if (amdgpu_sriov_vf(adev) && adev->asic_type == CHIP_SIENNA_CICHLID)  		adev->pm.pp_feature &= ~PP_OVERDRIVE_MASK; -	if (!amdgpu_device_pcie_dynamic_switching_supported()) +	if (!amdgpu_device_pcie_dynamic_switching_supported(adev))  		adev->pm.pp_feature &= ~PP_PCIE_DPM_MASK;  	total = true; @@ -2566,7 +2630,7 @@ static int amdgpu_device_init_schedulers(struct amdgpu_device *adev)  			break;  		} -		r = drm_sched_init(&ring->sched, &amdgpu_sched_ops, +		r = drm_sched_init(&ring->sched, &amdgpu_sched_ops, NULL,  				   DRM_SCHED_PRIORITY_COUNT,  				   ring->num_hw_submission, 0,  				   timeout, adev->reset_domain->wq, @@ -2669,6 +2733,12 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)  					goto init_failed;  				}  			} + +			r = amdgpu_seq64_init(adev); +			if (r) { +				DRM_ERROR("allocate seq64 failed %d\n", r); +				goto init_failed; +			}  		}  	} @@ -3131,6 +3201,7 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)  			amdgpu_device_wb_fini(adev);  			amdgpu_device_mem_scratch_fini(adev);  			amdgpu_ib_pool_fini(adev); +			amdgpu_seq64_fini(adev);  		}  		r = adev->ip_blocks[i].version->funcs->sw_fini((void *)adev); @@ -4050,23 +4121,13 @@ int amdgpu_device_init(struct amdgpu_device *adev,  				}  			}  		} else { -			switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { -			case IP_VERSION(13, 0, 0): -			case IP_VERSION(13, 0, 7): -			case IP_VERSION(13, 0, 10): -				r = psp_gpu_reset(adev); -				break; -			default: -				tmp = amdgpu_reset_method; -				/* It should do a default reset when loading or reloading the driver, -				 * regardless of the module parameter reset_method. -				 */ -				amdgpu_reset_method = AMD_RESET_METHOD_NONE; -				r = amdgpu_asic_reset(adev); -				amdgpu_reset_method = tmp; -				break; -			} - +			tmp = amdgpu_reset_method; +			/* It should do a default reset when loading or reloading the driver, +			 * regardless of the module parameter reset_method. +			 */ +			amdgpu_reset_method = AMD_RESET_METHOD_NONE; +			r = amdgpu_asic_reset(adev); +			amdgpu_reset_method = tmp;  			if (r) {  				dev_err(adev->dev, "asic reset on init failed\n");  				goto failed; @@ -4211,6 +4272,7 @@ fence_driver_init:  			"Could not create amdgpu board attributes\n");  	amdgpu_fru_sysfs_init(adev); +	amdgpu_reg_state_sysfs_init(adev);  	if (IS_ENABLED(CONFIG_PERF_EVENTS))  		r = amdgpu_pmu_init(adev); @@ -4333,6 +4395,8 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)  	sysfs_remove_files(&adev->dev->kobj, amdgpu_dev_attributes);  	amdgpu_fru_sysfs_fini(adev); +	amdgpu_reg_state_sysfs_fini(adev); +  	/* disable ras feature must before hw fini */  	amdgpu_ras_pre_fini(adev); @@ -4957,7 +5021,7 @@ bool amdgpu_device_has_job_running(struct amdgpu_device *adev)  	for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {  		struct amdgpu_ring *ring = adev->rings[i]; -		if (!ring || !ring->sched.thread) +		if (!amdgpu_ring_sched_ready(ring))  			continue;  		spin_lock(&ring->sched.job_list_lock); @@ -5096,7 +5160,7 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,  	for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {  		struct amdgpu_ring *ring = adev->rings[i]; -		if (!ring || !ring->sched.thread) +		if (!amdgpu_ring_sched_ready(ring))  			continue;  		/* Clear job fence from fence drv to avoid force_completion @@ -5172,7 +5236,6 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,  	struct amdgpu_device *tmp_adev = NULL;  	bool need_full_reset, skip_hw_reset, vram_lost = false;  	int r = 0; -	bool gpu_reset_for_dev_remove = 0;  	/* Try reset handler method first */  	tmp_adev = list_first_entry(device_list_handle, struct amdgpu_device, @@ -5192,10 +5255,6 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,  		test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);  	skip_hw_reset = test_bit(AMDGPU_SKIP_HW_RESET, &reset_context->flags); -	gpu_reset_for_dev_remove = -		test_bit(AMDGPU_RESET_FOR_DEVICE_REMOVE, &reset_context->flags) && -			test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags); -  	/*  	 * ASIC reset has to be done on all XGMI hive nodes ASAP  	 * to allow proper links negotiation in FW (within 1 sec) @@ -5238,18 +5297,6 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,  		amdgpu_ras_intr_cleared();  	} -	/* Since the mode1 reset affects base ip blocks, the -	 * phase1 ip blocks need to be resumed. Otherwise there -	 * will be a BIOS signature error and the psp bootloader -	 * can't load kdb on the next amdgpu install. -	 */ -	if (gpu_reset_for_dev_remove) { -		list_for_each_entry(tmp_adev, device_list_handle, reset_list) -			amdgpu_device_ip_resume_phase1(tmp_adev); - -		goto end; -	} -  	list_for_each_entry(tmp_adev, device_list_handle, reset_list) {  		if (need_full_reset) {  			/* post card */ @@ -5486,11 +5533,6 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,  	int i, r = 0;  	bool need_emergency_restart = false;  	bool audio_suspended = false; -	bool gpu_reset_for_dev_remove = false; - -	gpu_reset_for_dev_remove = -			test_bit(AMDGPU_RESET_FOR_DEVICE_REMOVE, &reset_context->flags) && -				test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);  	/*  	 * Special case: RAS triggered and full reset isn't supported @@ -5528,7 +5570,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,  	if (!amdgpu_sriov_vf(adev) && (adev->gmc.xgmi.num_physical_nodes > 1)) {  		list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) {  			list_add_tail(&tmp_adev->reset_list, &device_list); -			if (gpu_reset_for_dev_remove && adev->shutdown) +			if (adev->shutdown)  				tmp_adev->shutdown = true;  		}  		if (!list_is_first(&adev->reset_list, &device_list)) @@ -5585,7 +5627,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,  		for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {  			struct amdgpu_ring *ring = tmp_adev->rings[i]; -			if (!ring || !ring->sched.thread) +			if (!amdgpu_ring_sched_ready(ring))  				continue;  			drm_sched_stop(&ring->sched, job ? &job->base : NULL); @@ -5613,10 +5655,6 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,  retry:	/* Rest of adevs pre asic reset from XGMI hive. */  	list_for_each_entry(tmp_adev, device_list_handle, reset_list) { -		if (gpu_reset_for_dev_remove) { -			/* Workaroud for ASICs need to disable SMC first */ -			amdgpu_device_smu_fini_early(tmp_adev); -		}  		r = amdgpu_device_pre_asic_reset(tmp_adev, reset_context);  		/*TODO Should we stop ?*/  		if (r) { @@ -5648,9 +5686,6 @@ retry:	/* Rest of adevs pre asic reset from XGMI hive. */  		r = amdgpu_do_asic_reset(device_list_handle, reset_context);  		if (r && r == -EAGAIN)  			goto retry; - -		if (!r && gpu_reset_for_dev_remove) -			goto recover_end;  	}  skip_hw_reset: @@ -5661,7 +5696,7 @@ skip_hw_reset:  		for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {  			struct amdgpu_ring *ring = tmp_adev->rings[i]; -			if (!ring || !ring->sched.thread) +			if (!amdgpu_ring_sched_ready(ring))  				continue;  			drm_sched_start(&ring->sched, true); @@ -5706,7 +5741,6 @@ skip_sched_resume:  		amdgpu_ras_set_error_query_ready(tmp_adev, true);  	} -recover_end:  	tmp_adev = list_first_entry(device_list_handle, struct amdgpu_device,  					    reset_list);  	amdgpu_device_unlock_reset_domain(tmp_adev->reset_domain); @@ -5724,6 +5758,39 @@ recover_end:  }  /** + * amdgpu_device_partner_bandwidth - find the bandwidth of appropriate partner + * + * @adev: amdgpu_device pointer + * @speed: pointer to the speed of the link + * @width: pointer to the width of the link + * + * Evaluate the hierarchy to find the speed and bandwidth capabilities of the + * first physical partner to an AMD dGPU. + * This will exclude any virtual switches and links. + */ +static void amdgpu_device_partner_bandwidth(struct amdgpu_device *adev, +					    enum pci_bus_speed *speed, +					    enum pcie_link_width *width) +{ +	struct pci_dev *parent = adev->pdev; + +	if (!speed || !width) +		return; + +	*speed = PCI_SPEED_UNKNOWN; +	*width = PCIE_LNK_WIDTH_UNKNOWN; + +	while ((parent = pci_upstream_bridge(parent))) { +		/* skip upstream/downstream switches internal to dGPU*/ +		if (parent->vendor == PCI_VENDOR_ID_ATI) +			continue; +		*speed = pcie_get_speed_cap(parent); +		*width = pcie_get_width_cap(parent); +		break; +	} +} + +/**   * amdgpu_device_get_pcie_info - fence pcie info about the PCIE slot   *   * @adev: amdgpu_device pointer @@ -5756,8 +5823,8 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)  	if (adev->pm.pcie_gen_mask && adev->pm.pcie_mlw_mask)  		return; -	pcie_bandwidth_available(adev->pdev, NULL, -				 &platform_speed_cap, &platform_link_width); +	amdgpu_device_partner_bandwidth(adev, &platform_speed_cap, +					&platform_link_width);  	if (adev->pm.pcie_gen_mask == 0) {  		/* asic caps */ @@ -5984,7 +6051,7 @@ pci_ers_result_t amdgpu_pci_error_detected(struct pci_dev *pdev, pci_channel_sta  		for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {  			struct amdgpu_ring *ring = adev->rings[i]; -			if (!ring || !ring->sched.thread) +			if (!amdgpu_ring_sched_ready(ring))  				continue;  			drm_sched_stop(&ring->sched, NULL); @@ -6112,7 +6179,7 @@ void amdgpu_pci_resume(struct pci_dev *pdev)  	for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {  		struct amdgpu_ring *ring = adev->rings[i]; -		if (!ring || !ring->sched.thread) +		if (!amdgpu_ring_sched_ready(ring))  			continue;  		drm_sched_start(&ring->sched, true); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c index 0431eafa86b5..c7d60dd0fb97 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c @@ -1963,8 +1963,6 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev)  		amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);  		break;  	case IP_VERSION(9, 4, 3): -		if (!amdgpu_exp_hw_support) -			return -EINVAL;  		amdgpu_device_ip_block_add(adev, &gfx_v9_4_3_ip_block);  		break;  	case IP_VERSION(10, 1, 10): diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c index e7e87a3b2601..decbbe3d4f06 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c @@ -42,6 +42,7 @@  #include <linux/dma-fence-array.h>  #include <linux/pci-p2pdma.h>  #include <linux/pm_runtime.h> +#include "amdgpu_trace.h"  /**   * amdgpu_dma_buf_attach - &dma_buf_ops.attach implementation @@ -63,6 +64,7 @@ static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf,  		attach->peer2peer = false;  	r = pm_runtime_get_sync(adev_to_drm(adev)->dev); +	trace_amdgpu_runpm_reference_dumps(1, __func__);  	if (r < 0)  		goto out; @@ -70,6 +72,7 @@ static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf,  out:  	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); +	trace_amdgpu_runpm_reference_dumps(0, __func__);  	return r;  } @@ -90,6 +93,7 @@ static void amdgpu_dma_buf_detach(struct dma_buf *dmabuf,  	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);  	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); +	trace_amdgpu_runpm_reference_dumps(0, __func__);  }  /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 8b33b130ea36..971acf01bea6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -115,9 +115,10 @@   *   3.54.0 - Add AMDGPU_CTX_QUERY2_FLAGS_RESET_IN_PROGRESS support   * - 3.55.0 - Add AMDGPU_INFO_GPUVM_FAULT query   * - 3.56.0 - Update IB start address and size alignment for decode and encode + * - 3.57.0 - Compute tunneling on GFX10+   */  #define KMS_DRIVER_MAJOR	3 -#define KMS_DRIVER_MINOR	56 +#define KMS_DRIVER_MINOR	57  #define KMS_DRIVER_PATCHLEVEL	0  /* @@ -127,6 +128,7 @@ enum AMDGPU_DEBUG_MASK {  	AMDGPU_DEBUG_VM = BIT(0),  	AMDGPU_DEBUG_LARGEBAR = BIT(1),  	AMDGPU_DEBUG_DISABLE_GPU_SOFT_RECOVERY = BIT(2), +	AMDGPU_DEBUG_USE_VRAM_FW_BUF = BIT(3),  };  unsigned int amdgpu_vram_limit = UINT_MAX; @@ -208,6 +210,7 @@ int amdgpu_umsch_mm;  int amdgpu_seamless = -1; /* auto */  uint amdgpu_debug_mask;  int amdgpu_agp = -1; /* auto */ +int amdgpu_wbrf = -1;  static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work); @@ -971,6 +974,22 @@ module_param_named(debug_mask, amdgpu_debug_mask, uint, 0444);  MODULE_PARM_DESC(agp, "AGP (-1 = auto (default), 0 = disable, 1 = enable)");  module_param_named(agp, amdgpu_agp, int, 0444); +/** + * DOC: wbrf (int) + * Enable Wifi RFI interference mitigation feature. + * Due to electrical and mechanical constraints there may be likely interference of + * relatively high-powered harmonics of the (G-)DDR memory clocks with local radio + * module frequency bands used by Wifi 6/6e/7. To mitigate the possible RFI interference, + * with this feature enabled, PMFW will use either “shadowed P-State” or “P-State” based + * on active list of frequencies in-use (to be avoided) as part of initial setting or + * P-state transition. However, there may be potential performance impact with this + * feature enabled. + * (0 = disabled, 1 = enabled, -1 = auto (default setting, will be enabled if supported)) + */ +MODULE_PARM_DESC(wbrf, +	"Enable Wifi RFI interference mitigation (0 = disabled, 1 = enabled, -1 = auto(default)"); +module_param_named(wbrf, amdgpu_wbrf, int, 0444); +  /* These devices are not supported by amdgpu.   * They are supported by the mach64, r128, radeon drivers   */ @@ -2099,6 +2118,11 @@ static void amdgpu_init_debug_options(struct amdgpu_device *adev)  		pr_info("debug: soft reset for GPU recovery disabled\n");  		adev->debug_disable_soft_recovery = true;  	} + +	if (amdgpu_debug_mask & AMDGPU_DEBUG_USE_VRAM_FW_BUF) { +		pr_info("debug: place fw in vram for frontdoor loading\n"); +		adev->debug_use_vram_fw_buf = true; +	}  }  static unsigned long amdgpu_fix_asic_type(struct pci_dev *pdev, unsigned long flags) @@ -2210,6 +2234,8 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,  	pci_set_drvdata(pdev, ddev); +	amdgpu_init_debug_options(adev); +  	ret = amdgpu_driver_load_kms(adev, flags);  	if (ret)  		goto err_pci; @@ -2229,6 +2255,10 @@ retry_init:  	if (ret)  		goto err_pci; +	ret = amdgpu_amdkfd_drm_client_create(adev); +	if (ret) +		goto err_pci; +  	/*  	 * 1. don't init fbdev on hw without DCE  	 * 2. don't init fbdev if there are no connectors @@ -2290,8 +2320,6 @@ retry_init:  			amdgpu_get_secondary_funcs(adev);  	} -	amdgpu_init_debug_options(adev); -  	return 0;  err_pci: @@ -2313,38 +2341,6 @@ amdgpu_pci_remove(struct pci_dev *pdev)  		pm_runtime_forbid(dev->dev);  	} -	if (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 2) && -	    !amdgpu_sriov_vf(adev)) { -		bool need_to_reset_gpu = false; - -		if (adev->gmc.xgmi.num_physical_nodes > 1) { -			struct amdgpu_hive_info *hive; - -			hive = amdgpu_get_xgmi_hive(adev); -			if (hive->device_remove_count == 0) -				need_to_reset_gpu = true; -			hive->device_remove_count++; -			amdgpu_put_xgmi_hive(hive); -		} else { -			need_to_reset_gpu = true; -		} - -		/* Workaround for ASICs need to reset SMU. -		 * Called only when the first device is removed. -		 */ -		if (need_to_reset_gpu) { -			struct amdgpu_reset_context reset_context; - -			adev->shutdown = true; -			memset(&reset_context, 0, sizeof(reset_context)); -			reset_context.method = AMD_RESET_METHOD_NONE; -			reset_context.reset_req_dev = adev; -			set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags); -			set_bit(AMDGPU_RESET_FOR_DEVICE_REMOVE, &reset_context.flags); -			amdgpu_device_gpu_recover(adev, NULL, &reset_context); -		} -	} -  	amdgpu_driver_unload_kms(dev);  	/* diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index dc230212746a..70bff8cecfda 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -183,6 +183,7 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f, struct amd  	amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr,  			       seq, flags | AMDGPU_FENCE_FLAG_INT);  	pm_runtime_get_noresume(adev_to_drm(adev)->dev); +	trace_amdgpu_runpm_reference_dumps(1, __func__);  	ptr = &ring->fence_drv.fences[seq & ring->fence_drv.num_fences_mask];  	if (unlikely(rcu_dereference_protected(*ptr, 1))) {  		struct dma_fence *old; @@ -310,6 +311,7 @@ bool amdgpu_fence_process(struct amdgpu_ring *ring)  		dma_fence_put(fence);  		pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);  		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); +		trace_amdgpu_runpm_reference_dumps(0, __func__);  	} while (last_seq != seq);  	return true; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c index 73b8cca35bab..c623e23049d1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c @@ -121,6 +121,7 @@ int amdgpu_gart_table_ram_alloc(struct amdgpu_device *adev)  	struct amdgpu_bo_param bp;  	dma_addr_t dma_addr;  	struct page *p; +	unsigned long x;  	int ret;  	if (adev->gart.bo != NULL) @@ -130,6 +131,10 @@ int amdgpu_gart_table_ram_alloc(struct amdgpu_device *adev)  	if (!p)  		return -ENOMEM; +	/* assign pages to this device */ +	for (x = 0; x < (1UL << order); x++) +		p[x].mapping = adev->mman.bdev.dev_mapping; +  	/* If the hardware does not support UTCL2 snooping of the CPU caches  	 * then set_memory_wc() could be used as a workaround to mark the pages  	 * as write combine memory. @@ -223,6 +228,7 @@ void amdgpu_gart_table_ram_free(struct amdgpu_device *adev)  	unsigned int order = get_order(adev->gart.table_size);  	struct sg_table *sg = adev->gart.bo->tbo.sg;  	struct page *p; +	unsigned long x;  	int ret;  	ret = amdgpu_bo_reserve(adev->gart.bo, false); @@ -234,6 +240,8 @@ void amdgpu_gart_table_ram_free(struct amdgpu_device *adev)  	sg_free_table(sg);  	kfree(sg);  	p = virt_to_page(adev->gart.ptr); +	for (x = 0; x < (1UL << order); x++) +		p[x].mapping = NULL;  	__free_pages(p, order);  	adev->gart.ptr = NULL; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 84beeaa4d21c..49a5f1c73b3e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -203,7 +203,7 @@ static void amdgpu_gem_object_close(struct drm_gem_object *obj,  	struct drm_exec exec;  	long r; -	drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES); +	drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0);  	drm_exec_until_all_locked(&exec) {  		r = drm_exec_prepare_obj(&exec, &bo->tbo.base, 1);  		drm_exec_retry_on_contention(&exec); @@ -739,7 +739,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,  	}  	drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT | -		      DRM_EXEC_IGNORE_DUPLICATES); +		      DRM_EXEC_IGNORE_DUPLICATES, 0);  	drm_exec_until_all_locked(&exec) {  		if (gobj) {  			r = drm_exec_lock_obj(&exec, gobj); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c index d2f273d77e59..55784a9f26c4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c @@ -1045,21 +1045,28 @@ int amdgpu_gmc_vram_checking(struct amdgpu_device *adev)  	 * seconds, so here, we just pick up three parts for emulation.  	 */  	ret = memcmp(vram_ptr, cptr, 10); -	if (ret) -		return ret; +	if (ret) { +		ret = -EIO; +		goto release_buffer; +	}  	ret = memcmp(vram_ptr + (size / 2), cptr, 10); -	if (ret) -		return ret; +	if (ret) { +		ret = -EIO; +		goto release_buffer; +	}  	ret = memcmp(vram_ptr + size - 10, cptr, 10); -	if (ret) -		return ret; +	if (ret) { +		ret = -EIO; +		goto release_buffer; +	} +release_buffer:  	amdgpu_bo_free_kernel(&vram_bo, &vram_gpu,  			&vram_ptr); -	return 0; +	return ret;  }  static ssize_t current_memory_partition_show( diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c index 081267161d40..55b65fc04b65 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c @@ -190,8 +190,8 @@ int amdgpu_hmm_range_get_pages(struct mmu_interval_notifier *notifier,  		pr_debug("hmm range: start = 0x%lx, end = 0x%lx",  			hmm_range->start, hmm_range->end); -		/* Assuming 128MB takes maximum 1 second to fault page address */ -		timeout = max((hmm_range->end - hmm_range->start) >> 27, 1UL); +		/* Assuming 64MB takes maximum 1 second to fault page address */ +		timeout = max((hmm_range->end - hmm_range->start) >> 26, 1UL);  		timeout *= HMM_RANGE_DEFAULT_TIMEOUT;  		timeout = jiffies + msecs_to_jiffies(timeout); @@ -199,6 +199,7 @@ retry:  		hmm_range->notifier_seq = mmu_interval_read_begin(notifier);  		r = hmm_range_fault(hmm_range);  		if (unlikely(r)) { +			schedule();  			/*  			 * FIXME: This timeout should encompass the retry from  			 * mmu_interval_read_retry() as well. @@ -212,7 +213,6 @@ retry:  			break;  		hmm_range->hmm_pfns += MAX_WALK_BYTE >> PAGE_SHIFT;  		hmm_range->start = hmm_range->end; -		schedule();  	} while (hmm_range->end < end);  	hmm_range->start = start; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c index 82608df43396..d79cb13e1aa8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c @@ -175,7 +175,6 @@ struct amdgpu_i2c_chan *amdgpu_i2c_create(struct drm_device *dev,  	i2c->rec = *rec;  	i2c->adapter.owner = THIS_MODULE; -	i2c->adapter.class = I2C_CLASS_DDC;  	i2c->adapter.dev.parent = dev->dev;  	i2c->dev = dev;  	i2c_set_adapdata(&i2c->adapter, i2c); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index 1f357198533f..71a5cf37b472 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -115,7 +115,7 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, struct amdgpu_vm *vm,  	if (!entity)  		return 0; -	return drm_sched_job_init(&(*job)->base, entity, owner); +	return drm_sched_job_init(&(*job)->base, entity, 1, owner);  }  int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, @@ -325,7 +325,7 @@ void amdgpu_job_stop_all_jobs_on_sched(struct drm_gpu_scheduler *sched)  	int i;  	/* Signal all jobs not yet scheduled */ -	for (i = sched->num_rqs - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) { +	for (i = DRM_SCHED_PRIORITY_KERNEL; i < sched->num_rqs; i++) {  		struct drm_sched_rq *rq = sched->sched_rq[i];  		spin_lock(&rq->lock);  		list_for_each_entry(s_entity, &rq->entities, list) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 583cf03950cd..bf4f48fe438d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -1105,7 +1105,12 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)  			if (amdgpu_dpm_read_sensor(adev,  						   AMDGPU_PP_SENSOR_GPU_AVG_POWER,  						   (void *)&ui32, &ui32_size)) { -				return -EINVAL; +				/* fall back to input power for backwards compat */ +				if (amdgpu_dpm_read_sensor(adev, +							   AMDGPU_PP_SENSOR_GPU_INPUT_POWER, +							   (void *)&ui32, &ui32_size)) { +					return -EINVAL; +				}  			}  			ui32 >>= 8;  			break; @@ -1428,6 +1433,8 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,  		fpriv->csa_va = NULL;  	} +	amdgpu_seq64_unmap(adev, fpriv); +  	pasid = fpriv->vm.pasid;  	pd = amdgpu_bo_ref(fpriv->vm.root.bo);  	if (!WARN_ON(amdgpu_bo_reserve(pd, true))) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c index cf33eb219e25..59fafb8392e0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c @@ -218,6 +218,7 @@ static void amdgpu_mca_smu_mca_bank_dump(struct amdgpu_device *adev, int idx, st  int amdgpu_mca_smu_log_ras_error(struct amdgpu_device *adev, enum amdgpu_ras_block blk, enum amdgpu_mca_error_type type, struct ras_err_data *err_data)  {  	struct amdgpu_smuio_mcm_config_info mcm_info; +	struct ras_err_addr err_addr = {0};  	struct mca_bank_set mca_set;  	struct mca_bank_node *node;  	struct mca_bank_entry *entry; @@ -246,10 +247,18 @@ int amdgpu_mca_smu_log_ras_error(struct amdgpu_device *adev, enum amdgpu_ras_blo  		mcm_info.socket_id = entry->info.socket_id;  		mcm_info.die_id = entry->info.aid; +		if (blk == AMDGPU_RAS_BLOCK__UMC) { +			err_addr.err_status = entry->regs[MCA_REG_IDX_STATUS]; +			err_addr.err_ipid = entry->regs[MCA_REG_IDX_IPID]; +			err_addr.err_addr = entry->regs[MCA_REG_IDX_ADDR]; +		} +  		if (type == AMDGPU_MCA_ERROR_TYPE_UE) -			amdgpu_ras_error_statistic_ue_count(err_data, &mcm_info, (uint64_t)count); +			amdgpu_ras_error_statistic_ue_count(err_data, +				&mcm_info, &err_addr, (uint64_t)count);  		else -			amdgpu_ras_error_statistic_ce_count(err_data, &mcm_info, (uint64_t)count); +			amdgpu_ras_error_statistic_ce_count(err_data, +				&mcm_info, &err_addr, (uint64_t)count);  	}  out_mca_release: @@ -351,6 +360,9 @@ int amdgpu_mca_smu_get_mca_entry(struct amdgpu_device *adev, enum amdgpu_mca_err  	const struct amdgpu_mca_smu_funcs *mca_funcs = adev->mca.mca_funcs;  	int count; +	if (!mca_funcs || !mca_funcs->mca_get_mca_entry) +		return -EOPNOTSUPP; +  	switch (type) {  	case AMDGPU_MCA_ERROR_TYPE_UE:  		count = mca_funcs->max_ue_count; @@ -365,10 +377,7 @@ int amdgpu_mca_smu_get_mca_entry(struct amdgpu_device *adev, enum amdgpu_mca_err  	if (idx >= count)  		return -EINVAL; -	if (mca_funcs && mca_funcs->mca_get_mca_entry) -		return mca_funcs->mca_get_mca_entry(adev, type, idx, entry); - -	return -EOPNOTSUPP; +	return mca_funcs->mca_get_mca_entry(adev, type, idx, entry);  }  #if defined(CONFIG_DEBUG_FS) @@ -377,7 +386,7 @@ static int amdgpu_mca_smu_debug_mode_set(void *data, u64 val)  	struct amdgpu_device *adev = (struct amdgpu_device *)data;  	int ret; -	ret = amdgpu_mca_smu_set_debug_mode(adev, val ? true : false); +	ret = amdgpu_ras_set_mca_debug_mode(adev, val ? true : false);  	if (ret)  		return ret; @@ -485,7 +494,7 @@ DEFINE_DEBUGFS_ATTRIBUTE(mca_debug_mode_fops, NULL, amdgpu_mca_smu_debug_mode_se  void amdgpu_mca_smu_debugfs_init(struct amdgpu_device *adev, struct dentry *root)  {  #if defined(CONFIG_DEBUG_FS) -	if (!root || adev->ip_versions[MP1_HWIP][0] != IP_VERSION(13, 0, 6)) +	if (!root || amdgpu_ip_version(adev, MP1_HWIP, 0) != IP_VERSION(13, 0, 6))  		return;  	debugfs_create_file("mca_debug_mode", 0200, root, adev, &mca_debug_mode_fops); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h index e51e8918e667..b399f1b62887 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h @@ -46,6 +46,8 @@  #define MCA_REG__STATUS__ERRORCODEEXT(x)	MCA_REG_FIELD(x, 21, 16)  #define MCA_REG__STATUS__ERRORCODE(x)		MCA_REG_FIELD(x, 15, 0) +#define MCA_REG__MISC0__ERRCNT(x)		MCA_REG_FIELD(x, 43, 32) +  #define MCA_REG__SYND__ERRORINFORMATION(x)	MCA_REG_FIELD(x, 17, 0)  enum amdgpu_mca_ip { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c index 9ddbf1494326..da48b6da0107 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c @@ -98,6 +98,26 @@ static int amdgpu_mes_doorbell_init(struct amdgpu_device *adev)  	return 0;  } +static int amdgpu_mes_event_log_init(struct amdgpu_device *adev) +{ +	int r; + +	r = amdgpu_bo_create_kernel(adev, PAGE_SIZE, PAGE_SIZE, +				    AMDGPU_GEM_DOMAIN_GTT, +				    &adev->mes.event_log_gpu_obj, +				    &adev->mes.event_log_gpu_addr, +				    &adev->mes.event_log_cpu_addr); +	if (r) { +		dev_warn(adev->dev, "failed to create MES event log buffer (%d)", r); +		return r; +	} + +	memset(adev->mes.event_log_cpu_addr, 0, PAGE_SIZE); + +	return  0; + +} +  static void amdgpu_mes_doorbell_free(struct amdgpu_device *adev)  {  	bitmap_free(adev->mes.doorbell_bitmap); @@ -182,8 +202,14 @@ int amdgpu_mes_init(struct amdgpu_device *adev)  	if (r)  		goto error; +	r = amdgpu_mes_event_log_init(adev); +	if (r) +		goto error_doorbell; +  	return 0; +error_doorbell: +	amdgpu_mes_doorbell_free(adev);  error:  	amdgpu_device_wb_free(adev, adev->mes.sch_ctx_offs);  	amdgpu_device_wb_free(adev, adev->mes.query_status_fence_offs); @@ -199,6 +225,10 @@ error_ids:  void amdgpu_mes_fini(struct amdgpu_device *adev)  { +	amdgpu_bo_free_kernel(&adev->mes.event_log_gpu_obj, +			      &adev->mes.event_log_gpu_addr, +			      &adev->mes.event_log_cpu_addr); +  	amdgpu_device_wb_free(adev, adev->mes.sch_ctx_offs);  	amdgpu_device_wb_free(adev, adev->mes.query_status_fence_offs);  	amdgpu_device_wb_free(adev, adev->mes.read_val_offs); @@ -886,6 +916,11 @@ int amdgpu_mes_set_shader_debugger(struct amdgpu_device *adev,  	op_input.op = MES_MISC_OP_SET_SHADER_DEBUGGER;  	op_input.set_shader_debugger.process_context_addr = process_context_addr;  	op_input.set_shader_debugger.flags.u32all = flags; + +	/* use amdgpu mes_flush_shader_debugger instead */ +	if (op_input.set_shader_debugger.flags.process_ctx_flush) +		return -EINVAL; +  	op_input.set_shader_debugger.spi_gdbg_per_vmid_cntl = spi_gdbg_per_vmid_cntl;  	memcpy(op_input.set_shader_debugger.tcp_watch_cntl, tcp_watch_cntl,  			sizeof(op_input.set_shader_debugger.tcp_watch_cntl)); @@ -905,6 +940,32 @@ int amdgpu_mes_set_shader_debugger(struct amdgpu_device *adev,  	return r;  } +int amdgpu_mes_flush_shader_debugger(struct amdgpu_device *adev, +				     uint64_t process_context_addr) +{ +	struct mes_misc_op_input op_input = {0}; +	int r; + +	if (!adev->mes.funcs->misc_op) { +		DRM_ERROR("mes flush shader debugger is not supported!\n"); +		return -EINVAL; +	} + +	op_input.op = MES_MISC_OP_SET_SHADER_DEBUGGER; +	op_input.set_shader_debugger.process_context_addr = process_context_addr; +	op_input.set_shader_debugger.flags.process_ctx_flush = true; + +	amdgpu_mes_lock(&adev->mes); + +	r = adev->mes.funcs->misc_op(&adev->mes, &op_input); +	if (r) +		DRM_ERROR("failed to set_shader_debugger\n"); + +	amdgpu_mes_unlock(&adev->mes); + +	return r; +} +  static void  amdgpu_mes_ring_to_queue_props(struct amdgpu_device *adev,  			       struct amdgpu_ring *ring, @@ -1122,7 +1183,7 @@ int amdgpu_mes_ctx_map_meta_data(struct amdgpu_device *adev,  	amdgpu_sync_create(&sync); -	drm_exec_init(&exec, 0); +	drm_exec_init(&exec, 0, 0);  	drm_exec_until_all_locked(&exec) {  		r = drm_exec_lock_obj(&exec,  				      &ctx_data->meta_data_obj->tbo.base); @@ -1193,7 +1254,7 @@ int amdgpu_mes_ctx_unmap_meta_data(struct amdgpu_device *adev,  	struct drm_exec exec;  	long r; -	drm_exec_init(&exec, 0); +	drm_exec_init(&exec, 0, 0);  	drm_exec_until_all_locked(&exec) {  		r = drm_exec_lock_obj(&exec,  				      &ctx_data->meta_data_obj->tbo.base); @@ -1479,3 +1540,34 @@ out:  	amdgpu_ucode_release(&adev->mes.fw[pipe]);  	return r;  } + +#if defined(CONFIG_DEBUG_FS) + +static int amdgpu_debugfs_mes_event_log_show(struct seq_file *m, void *unused) +{ +	struct amdgpu_device *adev = m->private; +	uint32_t *mem = (uint32_t *)(adev->mes.event_log_cpu_addr); + +	seq_hex_dump(m, "", DUMP_PREFIX_OFFSET, 32, 4, +		     mem, PAGE_SIZE, false); + +	return 0; +} + + +DEFINE_SHOW_ATTRIBUTE(amdgpu_debugfs_mes_event_log); + +#endif + +void amdgpu_debugfs_mes_event_log_init(struct amdgpu_device *adev) +{ + +#if defined(CONFIG_DEBUG_FS) +	struct drm_minor *minor = adev_to_drm(adev)->primary; +	struct dentry *root = minor->debugfs_root; + +	debugfs_create_file("amdgpu_mes_event_log", 0444, root, +			    adev, &amdgpu_debugfs_mes_event_log_fops); + +#endif +} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h index a27b424ffe00..7d4f93fea937 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h @@ -133,6 +133,11 @@ struct amdgpu_mes {  	uint32_t			num_mes_dbs;  	unsigned long			*doorbell_bitmap; +	/* MES event log buffer */ +	struct amdgpu_bo		*event_log_gpu_obj; +	uint64_t                        event_log_gpu_addr; +	void				*event_log_cpu_addr; +  	/* ip specific functions */  	const struct amdgpu_mes_funcs   *funcs;  }; @@ -291,9 +296,10 @@ struct mes_misc_op_input {  			uint64_t process_context_addr;  			union {  				struct { -					uint64_t single_memop : 1; -					uint64_t single_alu_op : 1; -					uint64_t reserved: 30; +					uint32_t single_memop : 1; +					uint32_t single_alu_op : 1; +					uint32_t reserved: 29; +					uint32_t process_ctx_flush: 1;  				};  				uint32_t u32all;  			} flags; @@ -369,7 +375,8 @@ int amdgpu_mes_set_shader_debugger(struct amdgpu_device *adev,  				const uint32_t *tcp_watch_cntl,  				uint32_t flags,  				bool trap_en); - +int amdgpu_mes_flush_shader_debugger(struct amdgpu_device *adev, +				uint64_t process_context_addr);  int amdgpu_mes_add_ring(struct amdgpu_device *adev, int gang_id,  			int queue_type, int idx,  			struct amdgpu_mes_ctx_data *ctx_data, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index 32fe05c810c6..2e4911050cc5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -32,7 +32,6 @@  #include <drm/display/drm_dp_helper.h>  #include <drm/drm_crtc.h> -#include <drm/drm_edid.h>  #include <drm/drm_encoder.h>  #include <drm/drm_fixed.h>  #include <drm/drm_framebuffer.h> @@ -51,6 +50,7 @@ struct amdgpu_device;  struct amdgpu_encoder;  struct amdgpu_router;  struct amdgpu_hpd; +struct edid;  #define to_amdgpu_crtc(x) container_of(x, struct amdgpu_crtc, base)  #define to_amdgpu_connector(x) container_of(x, struct amdgpu_connector, base) @@ -343,6 +343,97 @@ struct amdgpu_mode_info {  	int			disp_priority;  	const struct amdgpu_display_funcs *funcs;  	const enum drm_plane_type *plane_type; + +	/* Driver-private color mgmt props */ + +	/* @plane_degamma_lut_property: Plane property to set a degamma LUT to +	 * convert encoded values to light linear values before sampling or +	 * blending. +	 */ +	struct drm_property *plane_degamma_lut_property; +	/* @plane_degamma_lut_size_property: Plane property to define the max +	 * size of degamma LUT as supported by the driver (read-only). +	 */ +	struct drm_property *plane_degamma_lut_size_property; +	/** +	 * @plane_degamma_tf_property: Plane pre-defined transfer function to +	 * to go from scanout/encoded values to linear values. +	 */ +	struct drm_property *plane_degamma_tf_property; +	/** +	 * @plane_hdr_mult_property: +	 */ +	struct drm_property *plane_hdr_mult_property; + +	struct drm_property *plane_ctm_property; +	/** +	 * @shaper_lut_property: Plane property to set pre-blending shaper LUT +	 * that converts color content before 3D LUT. If +	 * plane_shaper_tf_property != Identity TF, AMD color module will +	 * combine the user LUT values with pre-defined TF into the LUT +	 * parameters to be programmed. +	 */ +	struct drm_property *plane_shaper_lut_property; +	/** +	 * @shaper_lut_size_property: Plane property for the size of +	 * pre-blending shaper LUT as supported by the driver (read-only). +	 */ +	struct drm_property *plane_shaper_lut_size_property; +	/** +	 * @plane_shaper_tf_property: Plane property to set a predefined +	 * transfer function for pre-blending shaper (before applying 3D LUT) +	 * with or without LUT. There is no shaper ROM, but we can use AMD +	 * color modules to program LUT parameters from predefined TF (or +	 * from a combination of pre-defined TF and the custom 1D LUT). +	 */ +	struct drm_property *plane_shaper_tf_property; +	/** +	 * @plane_lut3d_property: Plane property for color transformation using +	 * a 3D LUT (pre-blending), a three-dimensional array where each +	 * element is an RGB triplet. Each dimension has the size of +	 * lut3d_size. The array contains samples from the approximated +	 * function. On AMD, values between samples are estimated by +	 * tetrahedral interpolation. The array is accessed with three indices, +	 * one for each input dimension (color channel), blue being the +	 * outermost dimension, red the innermost. +	 */ +	struct drm_property *plane_lut3d_property; +	/** +	 * @plane_degamma_lut_size_property: Plane property to define the max +	 * size of 3D LUT as supported by the driver (read-only). The max size +	 * is the max size of one dimension and, therefore, the max number of +	 * entries for 3D LUT array is the 3D LUT size cubed; +	 */ +	struct drm_property *plane_lut3d_size_property; +	/** +	 * @plane_blend_lut_property: Plane property for output gamma before +	 * blending. Userspace set a blend LUT to convert colors after 3D LUT +	 * conversion. It works as a post-3DLUT 1D LUT. With shaper LUT, they +	 * are sandwiching 3D LUT with two 1D LUT. If plane_blend_tf_property +	 * != Identity TF, AMD color module will combine the user LUT values +	 * with pre-defined TF into the LUT parameters to be programmed. +	 */ +	struct drm_property *plane_blend_lut_property; +	/** +	 * @plane_blend_lut_size_property: Plane property to define the max +	 * size of blend LUT as supported by the driver (read-only). +	 */ +	struct drm_property *plane_blend_lut_size_property; +	/** +	 * @plane_blend_tf_property: Plane property to set a predefined +	 * transfer function for pre-blending blend/out_gamma (after applying +	 * 3D LUT) with or without LUT. There is no blend ROM, but we can use +	 * AMD color modules to program LUT parameters from predefined TF (or +	 * from a combination of pre-defined TF and the custom 1D LUT). +	 */ +	struct drm_property *plane_blend_tf_property; +	/* @regamma_tf_property: Transfer function for CRTC regamma +	 * (post-blending). Possible values are defined by `enum +	 * amdgpu_transfer_function`. There is no regamma ROM, but we can use +	 * AMD color modules to program LUT parameters from predefined TF (or +	 * from a combination of pre-defined TF and the custom 1D LUT). +	 */ +	struct drm_property *regamma_tf_property;  };  #define AMDGPU_MAX_BL_LEVEL 0xFF @@ -416,6 +507,10 @@ struct amdgpu_crtc {  	int otg_inst;  	struct drm_pending_vblank_event *event; + +	bool wb_pending; +	bool wb_enabled; +	struct drm_writeback_connector *wb_conn;  };  struct amdgpu_encoder_atom_dig { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 5ad03f2afdb4..425cebcc5cbf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -1245,19 +1245,15 @@ int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer,   * amdgpu_bo_move_notify - notification about a memory move   * @bo: pointer to a buffer object   * @evict: if this move is evicting the buffer from the graphics address space - * @new_mem: new information of the bufer object   *   * Marks the corresponding &amdgpu_bo buffer object as invalid, also performs   * bookkeeping.   * TTM driver callback which is called when ttm moves a buffer.   */ -void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, -			   bool evict, -			   struct ttm_resource *new_mem) +void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict)  {  	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);  	struct amdgpu_bo *abo; -	struct ttm_resource *old_mem = bo->resource;  	if (!amdgpu_bo_is_amdgpu_bo(bo))  		return; @@ -1274,13 +1270,6 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,  	/* remember the eviction */  	if (evict)  		atomic64_inc(&adev->num_evictions); - -	/* update statistics */ -	if (!new_mem) -		return; - -	/* move_notify is called before move happens */ -	trace_amdgpu_bo_move(abo, new_mem->mem_type, old_mem->mem_type);  }  void amdgpu_bo_get_memory(struct amdgpu_bo *bo, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h index d28e21baef16..a3ea8a82db23 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h @@ -344,9 +344,7 @@ int amdgpu_bo_set_metadata (struct amdgpu_bo *bo, void *metadata,  int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer,  			   size_t buffer_size, uint32_t *metadata_size,  			   uint64_t *flags); -void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, -			   bool evict, -			   struct ttm_resource *new_mem); +void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict);  void amdgpu_bo_release_notify(struct ttm_buffer_object *bo);  vm_fault_t amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo);  void amdgpu_bo_fence(struct amdgpu_bo *bo, struct dma_fence *fence, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index a21045d018f2..0328616473f8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -466,7 +466,7 @@ static int psp_sw_init(void *handle)  	}  	ret = amdgpu_bo_create_kernel(adev, PSP_1_MEG, PSP_1_MEG, -				      amdgpu_sriov_vf(adev) ? +				      (amdgpu_sriov_vf(adev) || adev->debug_use_vram_fw_buf) ?  				      AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT,  				      &psp->fw_pri_bo,  				      &psp->fw_pri_mc_addr, @@ -1433,8 +1433,8 @@ int psp_xgmi_get_topology_info(struct psp_context *psp,  			 get_extended_data) ||  			amdgpu_ip_version(psp->adev, MP0_HWIP, 0) ==  				IP_VERSION(13, 0, 6); -		bool ta_port_num_support = psp->xgmi_context.xgmi_ta_caps & -						EXTEND_PEER_LINK_INFO_CMD_FLAG; +		bool ta_port_num_support = amdgpu_sriov_vf(psp->adev) ? 0 : +				psp->xgmi_context.xgmi_ta_caps & EXTEND_PEER_LINK_INFO_CMD_FLAG;  		/* popluate the shared output buffer rather than the cmd input buffer  		 * with node_ids as the input for GET_PEER_LINKS command execution. diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index 63fb4cd85e53..31823a30dea2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -305,11 +305,13 @@ static int amdgpu_ras_debugfs_ctrl_parse_data(struct file *f,  			return -EINVAL;  		data->head.block = block_id; -		/* only ue and ce errors are supported */ +		/* only ue, ce and poison errors are supported */  		if (!memcmp("ue", err, 2))  			data->head.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;  		else if (!memcmp("ce", err, 2))  			data->head.type = AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE; +		else if (!memcmp("poison", err, 6)) +			data->head.type = AMDGPU_RAS_ERROR__POISON;  		else  			return -EINVAL; @@ -431,9 +433,10 @@ static void amdgpu_ras_instance_mask_check(struct amdgpu_device *adev,   * The block is one of: umc, sdma, gfx, etc.   *	see ras_block_string[] for details   * - * The error type is one of: ue, ce, where, + * The error type is one of: ue, ce and poison where,   *	ue is multi-uncorrectable   *	ce is single-correctable + *	poison is poison   *   * The sub-block is a the sub-block index, pass 0 if there is no sub-block.   * The address and value are hexadecimal numbers, leading 0x is optional. @@ -1067,8 +1070,7 @@ static void amdgpu_ras_error_print_error_data(struct amdgpu_device *adev,  			mcm_info = &err_info->mcm_info;  			if (err_info->ce_count) {  				dev_info(adev->dev, "socket: %d, die: %d, " -					 "%lld new correctable hardware errors detected in %s block, " -					 "no user action is needed\n", +					 "%lld new correctable hardware errors detected in %s block\n",  					 mcm_info->socket_id,  					 mcm_info->die_id,  					 err_info->ce_count, @@ -1080,8 +1082,7 @@ static void amdgpu_ras_error_print_error_data(struct amdgpu_device *adev,  			err_info = &err_node->err_info;  			mcm_info = &err_info->mcm_info;  			dev_info(adev->dev, "socket: %d, die: %d, " -				 "%lld correctable hardware errors detected in total in %s block, " -				 "no user action is needed\n", +				 "%lld correctable hardware errors detected in total in %s block\n",  				 mcm_info->socket_id, mcm_info->die_id, err_info->ce_count, blk_name);  		}  	} @@ -1108,16 +1109,14 @@ static void amdgpu_ras_error_generate_report(struct amdgpu_device *adev,  			   adev->smuio.funcs->get_die_id) {  			dev_info(adev->dev, "socket: %d, die: %d "  				 "%ld correctable hardware errors " -				 "detected in %s block, no user " -				 "action is needed.\n", +				 "detected in %s block\n",  				 adev->smuio.funcs->get_socket_id(adev),  				 adev->smuio.funcs->get_die_id(adev),  				 ras_mgr->err_data.ce_count,  				 blk_name);  		} else {  			dev_info(adev->dev, "%ld correctable hardware errors " -				 "detected in %s block, no user " -				 "action is needed.\n", +				 "detected in %s block\n",  				 ras_mgr->err_data.ce_count,  				 blk_name);  		} @@ -1156,8 +1155,10 @@ static void amdgpu_rasmgr_error_data_statistic_update(struct ras_manager *obj, s  		for_each_ras_error(err_node, err_data) {  			err_info = &err_node->err_info; -			amdgpu_ras_error_statistic_ce_count(&obj->err_data, &err_info->mcm_info, err_info->ce_count); -			amdgpu_ras_error_statistic_ue_count(&obj->err_data, &err_info->mcm_info, err_info->ue_count); +			amdgpu_ras_error_statistic_ce_count(&obj->err_data, +					&err_info->mcm_info, NULL, err_info->ce_count); +			amdgpu_ras_error_statistic_ue_count(&obj->err_data, +					&err_info->mcm_info, NULL, err_info->ue_count);  		}  	} else {  		/* for legacy asic path which doesn't has error source info */ @@ -1174,6 +1175,9 @@ static int amdgpu_ras_query_error_status_helper(struct amdgpu_device *adev,  	enum amdgpu_ras_block blk = info ? info->head.block : AMDGPU_RAS_BLOCK_COUNT;  	struct amdgpu_ras_block_object *block_obj = NULL; +	if (blk == AMDGPU_RAS_BLOCK_COUNT) +		return -EINVAL; +  	if (error_query_mode == AMDGPU_RAS_INVALID_ERROR_QUERY)  		return -EINVAL; @@ -1915,7 +1919,7 @@ static void amdgpu_ras_interrupt_poison_creation_handler(struct ras_manager *obj  				struct amdgpu_iv_entry *entry)  {  	dev_info(obj->adev->dev, -		"Poison is created, no user action is needed.\n"); +		"Poison is created\n");  }  static void amdgpu_ras_interrupt_umc_handler(struct ras_manager *obj, @@ -2538,7 +2542,7 @@ int amdgpu_ras_recovery_init(struct amdgpu_device *adev)  		return 0;  	data = &con->eh_data; -	*data = kmalloc(sizeof(**data), GFP_KERNEL | __GFP_ZERO); +	*data = kzalloc(sizeof(**data), GFP_KERNEL);  	if (!*data) {  		ret = -ENOMEM;  		goto out; @@ -2825,10 +2829,10 @@ int amdgpu_ras_init(struct amdgpu_device *adev)  	if (con)  		return 0; -	con = kmalloc(sizeof(struct amdgpu_ras) + +	con = kzalloc(sizeof(*con) +  			sizeof(struct ras_manager) * AMDGPU_RAS_BLOCK_COUNT +  			sizeof(struct ras_manager) * AMDGPU_RAS_MCA_BLOCK_COUNT, -			GFP_KERNEL|__GFP_ZERO); +			GFP_KERNEL);  	if (!con)  		return -ENOMEM; @@ -2915,6 +2919,11 @@ int amdgpu_ras_init(struct amdgpu_device *adev)  	amdgpu_ras_query_poison_mode(adev); +	/* Packed socket_id to ras feature mask bits[31:29] */ +	if (adev->smuio.funcs && +	    adev->smuio.funcs->get_socket_id) +		con->features |= ((adev->smuio.funcs->get_socket_id(adev)) << 29); +  	/* Get RAS schema for particular SOC */  	con->schema = amdgpu_get_ras_schema(adev); @@ -3133,6 +3142,8 @@ int amdgpu_ras_late_init(struct amdgpu_device *adev)  	if (amdgpu_sriov_vf(adev))  		return 0; +	amdgpu_ras_set_mca_debug_mode(adev, false); +  	list_for_each_entry_safe(node, tmp, &adev->ras_list, node) {  		if (!node->ras_obj) {  			dev_warn(adev->dev, "Warning: abnormal ras list node.\n"); @@ -3406,12 +3417,18 @@ int amdgpu_ras_reset_gpu(struct amdgpu_device *adev)  	return 0;  } -void amdgpu_ras_set_mca_debug_mode(struct amdgpu_device *adev, bool enable) +int amdgpu_ras_set_mca_debug_mode(struct amdgpu_device *adev, bool enable)  {  	struct amdgpu_ras *con = amdgpu_ras_get_context(adev); +	int ret = 0; -	if (con) -		con->is_mca_debug_mode = enable; +	if (con) { +		ret = amdgpu_mca_smu_set_debug_mode(adev, enable); +		if (!ret) +			con->is_mca_debug_mode = enable; +	} + +	return ret;  }  bool amdgpu_ras_get_mca_debug_mode(struct amdgpu_device *adev) @@ -3682,7 +3699,8 @@ static int ras_err_info_cmp(void *priv, const struct list_head *a, const struct  }  static struct ras_err_info *amdgpu_ras_error_get_info(struct ras_err_data *err_data, -						      struct amdgpu_smuio_mcm_config_info *mcm_info) +				struct amdgpu_smuio_mcm_config_info *mcm_info, +				struct ras_err_addr *err_addr)  {  	struct ras_err_node *err_node; @@ -3696,6 +3714,9 @@ static struct ras_err_info *amdgpu_ras_error_get_info(struct ras_err_data *err_d  	memcpy(&err_node->err_info.mcm_info, mcm_info, sizeof(*mcm_info)); +	if (err_addr) +		memcpy(&err_node->err_info.err_addr, err_addr, sizeof(*err_addr)); +  	err_data->err_list_count++;  	list_add_tail(&err_node->node, &err_data->err_node_list);  	list_sort(NULL, &err_data->err_node_list, ras_err_info_cmp); @@ -3704,7 +3725,8 @@ static struct ras_err_info *amdgpu_ras_error_get_info(struct ras_err_data *err_d  }  int amdgpu_ras_error_statistic_ue_count(struct ras_err_data *err_data, -					struct amdgpu_smuio_mcm_config_info *mcm_info, u64 count) +		struct amdgpu_smuio_mcm_config_info *mcm_info, +		struct ras_err_addr *err_addr, u64 count)  {  	struct ras_err_info *err_info; @@ -3714,7 +3736,7 @@ int amdgpu_ras_error_statistic_ue_count(struct ras_err_data *err_data,  	if (!count)  		return 0; -	err_info = amdgpu_ras_error_get_info(err_data, mcm_info); +	err_info = amdgpu_ras_error_get_info(err_data, mcm_info, err_addr);  	if (!err_info)  		return -EINVAL; @@ -3725,7 +3747,8 @@ int amdgpu_ras_error_statistic_ue_count(struct ras_err_data *err_data,  }  int amdgpu_ras_error_statistic_ce_count(struct ras_err_data *err_data, -					struct amdgpu_smuio_mcm_config_info *mcm_info, u64 count) +		struct amdgpu_smuio_mcm_config_info *mcm_info, +		struct ras_err_addr *err_addr, u64 count)  {  	struct ras_err_info *err_info; @@ -3735,7 +3758,7 @@ int amdgpu_ras_error_statistic_ce_count(struct ras_err_data *err_data,  	if (!count)  		return 0; -	err_info = amdgpu_ras_error_get_info(err_data, mcm_info); +	err_info = amdgpu_ras_error_get_info(err_data, mcm_info, err_addr);  	if (!err_info)  		return -EINVAL; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h index 19161916ac46..76fb85628716 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h @@ -452,10 +452,17 @@ struct ras_fs_data {  	char debugfs_name[32];  }; +struct ras_err_addr { +	uint64_t err_status; +	uint64_t err_ipid; +	uint64_t err_addr; +}; +  struct ras_err_info {  	struct amdgpu_smuio_mcm_config_info mcm_info;  	u64 ce_count;  	u64 ue_count; +	struct ras_err_addr err_addr;  };  struct ras_err_node { @@ -773,7 +780,7 @@ struct amdgpu_ras* amdgpu_ras_get_context(struct amdgpu_device *adev);  int amdgpu_ras_set_context(struct amdgpu_device *adev, struct amdgpu_ras *ras_con); -void amdgpu_ras_set_mca_debug_mode(struct amdgpu_device *adev, bool enable); +int amdgpu_ras_set_mca_debug_mode(struct amdgpu_device *adev, bool enable);  bool amdgpu_ras_get_mca_debug_mode(struct amdgpu_device *adev);  bool amdgpu_ras_get_error_query_mode(struct amdgpu_device *adev,  				     unsigned int *mode); @@ -806,8 +813,10 @@ void amdgpu_ras_inst_reset_ras_error_count(struct amdgpu_device *adev,  int amdgpu_ras_error_data_init(struct ras_err_data *err_data);  void amdgpu_ras_error_data_fini(struct ras_err_data *err_data);  int amdgpu_ras_error_statistic_ce_count(struct ras_err_data *err_data, -					struct amdgpu_smuio_mcm_config_info *mcm_info, u64 count); +		struct amdgpu_smuio_mcm_config_info *mcm_info, +		struct ras_err_addr *err_addr, u64 count);  int amdgpu_ras_error_statistic_ue_count(struct ras_err_data *err_data, -					struct amdgpu_smuio_mcm_config_info *mcm_info, u64 count); +		struct amdgpu_smuio_mcm_config_info *mcm_info, +		struct ras_err_addr *err_addr, u64 count);  #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h index b0335a1c5e90..19899f6b9b2b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h @@ -32,7 +32,6 @@ enum AMDGPU_RESET_FLAGS {  	AMDGPU_NEED_FULL_RESET = 0,  	AMDGPU_SKIP_HW_RESET = 1, -	AMDGPU_RESET_FOR_DEVICE_REMOVE = 2,  };  struct amdgpu_reset_context { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 6a80d3ec887e..5505d646f43a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -635,6 +635,7 @@ int amdgpu_ring_test_helper(struct amdgpu_ring *ring)  			      ring->name);  	ring->sched.ready = !r; +  	return r;  } @@ -642,6 +643,10 @@ static void amdgpu_ring_to_mqd_prop(struct amdgpu_ring *ring,  				    struct amdgpu_mqd_prop *prop)  {  	struct amdgpu_device *adev = ring->adev; +	bool is_high_prio_compute = ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE && +				    amdgpu_gfx_is_high_priority_compute_queue(adev, ring); +	bool is_high_prio_gfx = ring->funcs->type == AMDGPU_RING_TYPE_GFX && +				amdgpu_gfx_is_high_priority_graphics_queue(adev, ring);  	memset(prop, 0, sizeof(*prop)); @@ -659,10 +664,8 @@ static void amdgpu_ring_to_mqd_prop(struct amdgpu_ring *ring,  	 */  	prop->hqd_active = ring->funcs->type == AMDGPU_RING_TYPE_KIQ; -	if ((ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE && -	     amdgpu_gfx_is_high_priority_compute_queue(adev, ring)) || -	    (ring->funcs->type == AMDGPU_RING_TYPE_GFX && -	     amdgpu_gfx_is_high_priority_graphics_queue(adev, ring))) { +	prop->allow_tunneling = is_high_prio_compute; +	if (is_high_prio_compute || is_high_prio_gfx) {  		prop->hqd_pipe_priority = AMDGPU_GFX_PIPE_PRIO_HIGH;  		prop->hqd_queue_priority = AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM;  	} @@ -715,3 +718,14 @@ void amdgpu_ring_ib_on_emit_de(struct amdgpu_ring *ring)  	if (ring->is_sw_ring)  		amdgpu_sw_ring_ib_mark_offset(ring, AMDGPU_MUX_OFFSET_TYPE_DE);  } + +bool amdgpu_ring_sched_ready(struct amdgpu_ring *ring) +{ +	if (!ring) +		return false; + +	if (ring->no_scheduler || !drm_sched_wqueue_ready(&ring->sched)) +		return false; + +	return true; +} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index bbb53720a018..fe1a61eb6e4c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -450,5 +450,5 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,  int amdgpu_ib_pool_init(struct amdgpu_device *adev);  void amdgpu_ib_pool_fini(struct amdgpu_device *adev);  int amdgpu_ib_ring_tests(struct amdgpu_device *adev); - +bool amdgpu_ring_sched_ready(struct amdgpu_ring *ring);  #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c index 35e0ae9acadc..2c3675d91614 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c @@ -531,13 +531,12 @@ int amdgpu_gfx_rlc_init_microcode(struct amdgpu_device *adev,  	if (version_major == 2 && version_minor == 1)  		adev->gfx.rlc.is_rlc_v2_1 = true; -	if (version_minor >= 0) { -		err = amdgpu_gfx_rlc_init_microcode_v2_0(adev); -		if (err) { -			dev_err(adev->dev, "fail to init rlc v2_0 microcode\n"); -			return err; -		} +	err = amdgpu_gfx_rlc_init_microcode_v2_0(adev); +	if (err) { +		dev_err(adev->dev, "fail to init rlc v2_0 microcode\n"); +		return err;  	} +  	if (version_minor >= 1)  		amdgpu_gfx_rlc_init_microcode_v2_1(adev);  	if (version_minor >= 2) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c new file mode 100644 index 000000000000..7a6a67275404 --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c @@ -0,0 +1,247 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright 2023 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "amdgpu.h" +#include "amdgpu_seq64.h" + +#include <drm/drm_exec.h> + +/** + * DOC: amdgpu_seq64 + * + * amdgpu_seq64 allocates a 64bit memory on each request in sequence order. + * seq64 driver is required for user queue fence memory allocation, TLB + * counters and VM updates. It has maximum count of 32768 64 bit slots. + */ + +/** + * amdgpu_seq64_map - Map the seq64 memory to VM + * + * @adev: amdgpu_device pointer + * @vm: vm pointer + * @bo_va: bo_va pointer + * @seq64_addr: seq64 vaddr start address + * @size: seq64 pool size + * + * Map the seq64 memory to the given VM. + * + * Returns: + * 0 on success or a negative error code on failure + */ +int amdgpu_seq64_map(struct amdgpu_device *adev, struct amdgpu_vm *vm, +		     struct amdgpu_bo_va **bo_va, u64 seq64_addr, +		     uint32_t size) +{ +	struct amdgpu_bo *bo; +	struct drm_exec exec; +	int r; + +	bo = adev->seq64.sbo; +	if (!bo) +		return -EINVAL; + +	drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0); +	drm_exec_until_all_locked(&exec) { +		r = amdgpu_vm_lock_pd(vm, &exec, 0); +		if (likely(!r)) +			r = drm_exec_lock_obj(&exec, &bo->tbo.base); +		drm_exec_retry_on_contention(&exec); +		if (unlikely(r)) +			goto error; +	} + +	*bo_va = amdgpu_vm_bo_add(adev, vm, bo); +	if (!*bo_va) { +		r = -ENOMEM; +		goto error; +	} + +	r = amdgpu_vm_bo_map(adev, *bo_va, seq64_addr, 0, size, +			     AMDGPU_PTE_READABLE | AMDGPU_PTE_WRITEABLE | +			     AMDGPU_PTE_EXECUTABLE); +	if (r) { +		DRM_ERROR("failed to do bo_map on userq sem, err=%d\n", r); +		amdgpu_vm_bo_del(adev, *bo_va); +		goto error; +	} + +	r = amdgpu_vm_bo_update(adev, *bo_va, false); +	if (r) { +		DRM_ERROR("failed to do vm_bo_update on userq sem\n"); +		amdgpu_vm_bo_del(adev, *bo_va); +		goto error; +	} + +error: +	drm_exec_fini(&exec); +	return r; +} + +/** + * amdgpu_seq64_unmap - Unmap the seq64 memory + * + * @adev: amdgpu_device pointer + * @fpriv: DRM file private + * + * Unmap the seq64 memory from the given VM. + */ +void amdgpu_seq64_unmap(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv) +{ +	struct amdgpu_vm *vm; +	struct amdgpu_bo *bo; +	struct drm_exec exec; +	int r; + +	if (!fpriv->seq64_va) +		return; + +	bo = adev->seq64.sbo; +	if (!bo) +		return; + +	vm = &fpriv->vm; + +	drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0); +	drm_exec_until_all_locked(&exec) { +		r = amdgpu_vm_lock_pd(vm, &exec, 0); +		if (likely(!r)) +			r = drm_exec_lock_obj(&exec, &bo->tbo.base); +		drm_exec_retry_on_contention(&exec); +		if (unlikely(r)) +			goto error; +	} + +	amdgpu_vm_bo_del(adev, fpriv->seq64_va); + +	fpriv->seq64_va = NULL; + +error: +	drm_exec_fini(&exec); +} + +/** + * amdgpu_seq64_alloc - Allocate a 64 bit memory + * + * @adev: amdgpu_device pointer + * @gpu_addr: allocated gpu VA start address + * @cpu_addr: allocated cpu VA start address + * + * Alloc a 64 bit memory from seq64 pool. + * + * Returns: + * 0 on success or a negative error code on failure + */ +int amdgpu_seq64_alloc(struct amdgpu_device *adev, u64 *gpu_addr, +		       u64 **cpu_addr) +{ +	unsigned long bit_pos; +	u32 offset; + +	bit_pos = find_first_zero_bit(adev->seq64.used, adev->seq64.num_sem); + +	if (bit_pos < adev->seq64.num_sem) { +		__set_bit(bit_pos, adev->seq64.used); +		offset = bit_pos << 6; /* convert to qw offset */ +	} else { +		return -EINVAL; +	} + +	*gpu_addr = offset + AMDGPU_SEQ64_VADDR_START; +	*cpu_addr = offset + adev->seq64.cpu_base_addr; + +	return 0; +} + +/** + * amdgpu_seq64_free - Free the given 64 bit memory + * + * @adev: amdgpu_device pointer + * @gpu_addr: gpu start address to be freed + * + * Free the given 64 bit memory from seq64 pool. + * + */ +void amdgpu_seq64_free(struct amdgpu_device *adev, u64 gpu_addr) +{ +	u32 offset; + +	offset = gpu_addr - AMDGPU_SEQ64_VADDR_START; + +	offset >>= 6; +	if (offset < adev->seq64.num_sem) +		__clear_bit(offset, adev->seq64.used); +} + +/** + * amdgpu_seq64_fini - Cleanup seq64 driver + * + * @adev: amdgpu_device pointer + * + * Free the memory space allocated for seq64. + * + */ +void amdgpu_seq64_fini(struct amdgpu_device *adev) +{ +	amdgpu_bo_free_kernel(&adev->seq64.sbo, +			      NULL, +			      (void **)&adev->seq64.cpu_base_addr); +} + +/** + * amdgpu_seq64_init - Initialize seq64 driver + * + * @adev: amdgpu_device pointer + * + * Allocate the required memory space for seq64. + * + * Returns: + * 0 on success or a negative error code on failure + */ +int amdgpu_seq64_init(struct amdgpu_device *adev) +{ +	int r; + +	if (adev->seq64.sbo) +		return 0; + +	/* +	 * AMDGPU_MAX_SEQ64_SLOTS * sizeof(u64) * 8 = AMDGPU_MAX_SEQ64_SLOTS +	 * 64bit slots +	 */ +	r = amdgpu_bo_create_kernel(adev, AMDGPU_SEQ64_SIZE, +				    PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT, +				    &adev->seq64.sbo, NULL, +				    (void **)&adev->seq64.cpu_base_addr); +	if (r) { +		dev_warn(adev->dev, "(%d) create seq64 failed\n", r); +		return r; +	} + +	memset(adev->seq64.cpu_base_addr, 0, AMDGPU_SEQ64_SIZE); + +	adev->seq64.num_sem = AMDGPU_MAX_SEQ64_SLOTS; +	memset(&adev->seq64.used, 0, sizeof(adev->seq64.used)); + +	return 0; +} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.h new file mode 100644 index 000000000000..2196e72be508 --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright 2023 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __AMDGPU_SEQ64_H__ +#define __AMDGPU_SEQ64_H__ + +#define AMDGPU_SEQ64_SIZE		(2ULL << 20) +#define AMDGPU_MAX_SEQ64_SLOTS		(AMDGPU_SEQ64_SIZE / (sizeof(u64) * 8)) +#define AMDGPU_SEQ64_VADDR_OFFSET	0x50000 +#define AMDGPU_SEQ64_VADDR_START	(AMDGPU_VA_RESERVED_SIZE + AMDGPU_SEQ64_VADDR_OFFSET) + +struct amdgpu_seq64 { +	struct amdgpu_bo *sbo; +	u32 num_sem; +	u64 *cpu_base_addr; +	DECLARE_BITMAP(used, AMDGPU_MAX_SEQ64_SLOTS); +}; + +void amdgpu_seq64_fini(struct amdgpu_device *adev); +int amdgpu_seq64_init(struct amdgpu_device *adev); +int amdgpu_seq64_alloc(struct amdgpu_device *adev, u64 *gpu_addr, u64 **cpu_addr); +void amdgpu_seq64_free(struct amdgpu_device *adev, u64 gpu_addr); +int amdgpu_seq64_map(struct amdgpu_device *adev, struct amdgpu_vm *vm, +		     struct amdgpu_bo_va **bo_va, u64 seq64_addr, uint32_t size); +void amdgpu_seq64_unmap(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv); + +#endif + diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c index dcd8c066bc1f..1b013a44ca99 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c @@ -191,7 +191,8 @@ static bool amdgpu_sync_test_fence(struct amdgpu_device *adev,  	/* Never sync to VM updates either. */  	if (fence_owner == AMDGPU_FENCE_OWNER_VM && -	    owner != AMDGPU_FENCE_OWNER_UNDEFINED) +	    owner != AMDGPU_FENCE_OWNER_UNDEFINED && +	    owner != AMDGPU_FENCE_OWNER_KFD)  		return false;  	/* Ignore fences depending on the sync mode */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h index 2fd1bfb35916..f539b1d00234 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h @@ -554,6 +554,21 @@ TRACE_EVENT(amdgpu_reset_reg_dumps,  		      __entry->value)  ); +TRACE_EVENT(amdgpu_runpm_reference_dumps, +	    TP_PROTO(uint32_t index, const char *func), +	    TP_ARGS(index, func), +	    TP_STRUCT__entry( +			     __field(uint32_t, index) +			     __string(func, func) +			     ), +	    TP_fast_assign( +			   __entry->index = index; +			   __assign_str(func, func); +			   ), +	    TP_printk("amdgpu runpm reference dump 0x%x: 0x%s\n", +		      __entry->index, +		      __get_str(func)) +);  #undef AMDGPU_JOB_GET_TIMELINE_NAME  #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index ab4a762aed5b..75c9fd2c6c2a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -545,10 +545,11 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,  			return r;  	} +	trace_amdgpu_bo_move(abo, new_mem->mem_type, old_mem->mem_type);  out:  	/* update statistics */  	atomic64_add(bo->base.size, &adev->num_bytes_moved); -	amdgpu_bo_move_notify(bo, evict, new_mem); +	amdgpu_bo_move_notify(bo, evict);  	return 0;  } @@ -1553,7 +1554,7 @@ static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo,  static void  amdgpu_bo_delete_mem_notify(struct ttm_buffer_object *bo)  { -	amdgpu_bo_move_notify(bo, false, NULL); +	amdgpu_bo_move_notify(bo, false);  }  static struct ttm_device_funcs amdgpu_bo_driver = { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c index b14127429f30..3e12763e477a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c @@ -1062,7 +1062,8 @@ int amdgpu_ucode_create_bo(struct amdgpu_device *adev)  {  	if (adev->firmware.load_type != AMDGPU_FW_LOAD_DIRECT) {  		amdgpu_bo_create_kernel(adev, adev->firmware.fw_size, PAGE_SIZE, -			amdgpu_sriov_vf(adev) ? AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT, +			(amdgpu_sriov_vf(adev) || adev->debug_use_vram_fw_buf) ? +			AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT,  			&adev->firmware.fw_buf,  			&adev->firmware.fw_buf_mc,  			&adev->firmware.fw_buf_ptr); @@ -1397,9 +1398,13 @@ int amdgpu_ucode_request(struct amdgpu_device *adev, const struct firmware **fw,  	if (err)  		return -ENODEV; +  	err = amdgpu_ucode_validate(*fw); -	if (err) +	if (err) {  		dev_dbg(adev->dev, "\"%s\" failed to validate\n", fw_name); +		release_firmware(*fw); +		*fw = NULL; +	}  	return err;  } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c index ca45ba8ac171..bfbf59326ee1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c @@ -86,7 +86,7 @@ static int map_ring_data(struct amdgpu_device *adev, struct amdgpu_vm *vm,  	amdgpu_sync_create(&sync); -	drm_exec_init(&exec, 0); +	drm_exec_init(&exec, 0, 0);  	drm_exec_until_all_locked(&exec) {  		r = drm_exec_lock_obj(&exec, &bo->tbo.base);  		drm_exec_retry_on_contention(&exec); @@ -149,7 +149,7 @@ static int unmap_ring_data(struct amdgpu_device *adev, struct amdgpu_vm *vm,  	struct drm_exec exec;  	long r; -	drm_exec_init(&exec, 0); +	drm_exec_init(&exec, 0, 0);  	drm_exec_until_all_locked(&exec) {  		r = drm_exec_lock_obj(&exec, &bo->tbo.base);  		drm_exec_retry_on_contention(&exec); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c index 3a632c3b1a2c..0dcff2889e25 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c @@ -1099,7 +1099,8 @@ bool amdgpu_sriov_xnack_support(struct amdgpu_device *adev)  {  	bool xnack_mode = true; -	if (amdgpu_sriov_vf(adev) && adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 2)) +	if (amdgpu_sriov_vf(adev) && +	    amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 2))  		xnack_mode = false;  	return xnack_mode; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c index db6fc0cb18eb..453a4b786cfc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c @@ -1,6 +1,7 @@  // SPDX-License-Identifier: GPL-2.0+  #include <drm/drm_atomic_helper.h> +#include <drm/drm_edid.h>  #include <drm/drm_simple_kms_helper.h>  #include <drm/drm_vblank.h> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 5baefb548a29..b8fcb6c55698 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1439,6 +1439,51 @@ int amdgpu_vm_handle_moved(struct amdgpu_device *adev,  }  /** + * amdgpu_vm_flush_compute_tlb - Flush TLB on compute VM + * + * @adev: amdgpu_device pointer + * @vm: requested vm + * @flush_type: flush type + * @xcc_mask: mask of XCCs that belong to the compute partition in need of a TLB flush. + * + * Flush TLB if needed for a compute VM. + * + * Returns: + * 0 for success. + */ +int amdgpu_vm_flush_compute_tlb(struct amdgpu_device *adev, +				struct amdgpu_vm *vm, +				uint32_t flush_type, +				uint32_t xcc_mask) +{ +	uint64_t tlb_seq = amdgpu_vm_tlb_seq(vm); +	bool all_hub = false; +	int xcc = 0, r = 0; + +	WARN_ON_ONCE(!vm->is_compute_context); + +	/* +	 * It can be that we race and lose here, but that is extremely unlikely +	 * and the worst thing which could happen is that we flush the changes +	 * into the TLB once more which is harmless. +	 */ +	if (atomic64_xchg(&vm->kfd_last_flushed_seq, tlb_seq) == tlb_seq) +		return 0; + +	if (adev->family == AMDGPU_FAMILY_AI || +	    adev->family == AMDGPU_FAMILY_RV) +		all_hub = true; + +	for_each_inst(xcc, xcc_mask) { +		r = amdgpu_gmc_flush_gpu_tlb_pasid(adev, vm->pasid, flush_type, +						   all_hub, xcc); +		if (r) +			break; +	} +	return r; +} + +/**   * amdgpu_vm_bo_add - add a bo to a specific vm   *   * @adev: amdgpu_device pointer diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index 2cd86d2bf73f..4740dd65b99d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h @@ -116,7 +116,7 @@ struct amdgpu_mem_stats;  #define AMDGPU_VM_FAULT_STOP_FIRST	1  #define AMDGPU_VM_FAULT_STOP_ALWAYS	2 -/* Reserve 4MB VRAM for page tables */ +/* How much VRAM be reserved for page tables */  #define AMDGPU_VM_RESERVED_VRAM		(8ULL << 20)  /* @@ -324,6 +324,7 @@ struct amdgpu_vm {  	/* Last finished delayed update */  	atomic64_t		tlb_seq;  	struct dma_fence	*last_tlb_flush; +	atomic64_t		kfd_last_flushed_seq;  	/* How many times we had to re-generate the page tables */  	uint64_t		generation; @@ -445,6 +446,10 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,  int amdgpu_vm_handle_moved(struct amdgpu_device *adev,  			   struct amdgpu_vm *vm,  			   struct ww_acquire_ctx *ticket); +int amdgpu_vm_flush_compute_tlb(struct amdgpu_device *adev, +				struct amdgpu_vm *vm, +				uint32_t flush_type, +				uint32_t xcc_mask);  void amdgpu_vm_bo_base_init(struct amdgpu_vm_bo_base *base,  			    struct amdgpu_vm *vm, struct amdgpu_bo *bo);  int amdgpu_vm_update_range(struct amdgpu_device *adev, struct amdgpu_vm *vm, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c index e81579708e96..b9a15d51eb5c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c @@ -26,6 +26,7 @@  #include "amdgpu.h"  #include "amdgpu_ucode.h"  #include "amdgpu_vpe.h" +#include "amdgpu_smu.h"  #include "soc15_common.h"  #include "vpe_v6_1.h" @@ -33,8 +34,180 @@  /* VPE CSA resides in the 4th page of CSA */  #define AMDGPU_CSA_VPE_OFFSET 	(4096 * 3) +/* 1 second timeout */ +#define VPE_IDLE_TIMEOUT	msecs_to_jiffies(1000) + +#define VPE_MAX_DPM_LEVEL			4 +#define FIXED1_8_BITS_PER_FRACTIONAL_PART	8 +#define GET_PRATIO_INTEGER_PART(x)		((x) >> FIXED1_8_BITS_PER_FRACTIONAL_PART) +  static void vpe_set_ring_funcs(struct amdgpu_device *adev); +static inline uint16_t div16_u16_rem(uint16_t dividend, uint16_t divisor, uint16_t *remainder) +{ +	*remainder = dividend % divisor; +	return dividend / divisor; +} + +static inline uint16_t complete_integer_division_u16( +	uint16_t dividend, +	uint16_t divisor, +	uint16_t *remainder) +{ +	return div16_u16_rem(dividend, divisor, (uint16_t *)remainder); +} + +static uint16_t vpe_u1_8_from_fraction(uint16_t numerator, uint16_t denominator) +{ +	u16 arg1_value = numerator; +	u16 arg2_value = denominator; + +	uint16_t remainder; + +	/* determine integer part */ +	uint16_t res_value = complete_integer_division_u16( +		arg1_value, arg2_value, &remainder); + +	if (res_value > 127 /* CHAR_MAX */) +		return 0; + +	/* determine fractional part */ +	{ +		unsigned int i = FIXED1_8_BITS_PER_FRACTIONAL_PART; + +		do { +			remainder <<= 1; + +			res_value <<= 1; + +			if (remainder >= arg2_value) { +				res_value |= 1; +				remainder -= arg2_value; +			} +		} while (--i != 0); +	} + +	/* round up LSB */ +	{ +		uint16_t summand = (remainder << 1) >= arg2_value; + +		if ((res_value + summand) > 32767 /* SHRT_MAX */) +			return 0; + +		res_value += summand; +	} + +	return res_value; +} + +static uint16_t vpe_internal_get_pratio(uint16_t from_frequency, uint16_t to_frequency) +{ +	uint16_t pratio = vpe_u1_8_from_fraction(from_frequency, to_frequency); + +	if (GET_PRATIO_INTEGER_PART(pratio) > 1) +		pratio = 0; + +	return pratio; +} + +/* + * VPE has 4 DPM levels from level 0 (lowerest) to 3 (highest), + * VPE FW will dynamically decide which level should be used according to current loading. + * + * Get VPE and SOC clocks from PM, and select the appropriate four clock values, + * calculate the ratios of adjusting from one clock to another. + * The VPE FW can then request the appropriate frequency from the PMFW. + */ +int amdgpu_vpe_configure_dpm(struct amdgpu_vpe *vpe) +{ +	struct amdgpu_device *adev = vpe->ring.adev; +	uint32_t dpm_ctl; + +	if (adev->pm.dpm_enabled) { +		struct dpm_clocks clock_table = { 0 }; +		struct dpm_clock *VPEClks; +		struct dpm_clock *SOCClks; +		uint32_t idx; +		uint32_t pratio_vmax_vnorm = 0, pratio_vnorm_vmid = 0, pratio_vmid_vmin = 0; +		uint16_t pratio_vmin_freq = 0, pratio_vmid_freq = 0, pratio_vnorm_freq = 0, pratio_vmax_freq = 0; + +		dpm_ctl = RREG32(vpe_get_reg_offset(vpe, 0, vpe->regs.dpm_enable)); +		dpm_ctl |= 1; /* DPM enablement */ +		WREG32(vpe_get_reg_offset(vpe, 0, vpe->regs.dpm_enable), dpm_ctl); + +		/* Get VPECLK and SOCCLK */ +		if (amdgpu_dpm_get_dpm_clock_table(adev, &clock_table)) { +			dev_dbg(adev->dev, "%s: get clock failed!\n", __func__); +			goto disable_dpm; +		} + +		SOCClks = clock_table.SocClocks; +		VPEClks = clock_table.VPEClocks; + +		/* vpe dpm only cares 4 levels. */ +		for (idx = 0; idx < VPE_MAX_DPM_LEVEL; idx++) { +			uint32_t soc_dpm_level; +			uint32_t min_freq; + +			if (idx == 0) +				soc_dpm_level = 0; +			else +				soc_dpm_level = (idx * 2) + 1; + +			/* clamp the max level */ +			if (soc_dpm_level > PP_SMU_NUM_VPECLK_DPM_LEVELS - 1) +				soc_dpm_level = PP_SMU_NUM_VPECLK_DPM_LEVELS - 1; + +			min_freq = (SOCClks[soc_dpm_level].Freq < VPEClks[soc_dpm_level].Freq) ? +				   SOCClks[soc_dpm_level].Freq : VPEClks[soc_dpm_level].Freq; + +			switch (idx) { +			case 0: +				pratio_vmin_freq = min_freq; +				break; +			case 1: +				pratio_vmid_freq = min_freq; +				break; +			case 2: +				pratio_vnorm_freq = min_freq; +				break; +			case 3: +				pratio_vmax_freq = min_freq; +				break; +			default: +				break; +			} +		} + +		if (pratio_vmin_freq && pratio_vmid_freq && pratio_vnorm_freq && pratio_vmax_freq) { +			uint32_t pratio_ctl; + +			pratio_vmax_vnorm = (uint32_t)vpe_internal_get_pratio(pratio_vmax_freq, pratio_vnorm_freq); +			pratio_vnorm_vmid = (uint32_t)vpe_internal_get_pratio(pratio_vnorm_freq, pratio_vmid_freq); +			pratio_vmid_vmin = (uint32_t)vpe_internal_get_pratio(pratio_vmid_freq, pratio_vmin_freq); + +			pratio_ctl = pratio_vmax_vnorm | (pratio_vnorm_vmid << 9) | (pratio_vmid_vmin << 18); +			WREG32(vpe_get_reg_offset(vpe, 0, vpe->regs.dpm_pratio), pratio_ctl);		/* PRatio */ +			WREG32(vpe_get_reg_offset(vpe, 0, vpe->regs.dpm_request_interval), 24000);	/* 1ms, unit=1/24MHz */ +			WREG32(vpe_get_reg_offset(vpe, 0, vpe->regs.dpm_decision_threshold), 1200000);	/* 50ms */ +			WREG32(vpe_get_reg_offset(vpe, 0, vpe->regs.dpm_busy_clamp_threshold), 1200000);/* 50ms */ +			WREG32(vpe_get_reg_offset(vpe, 0, vpe->regs.dpm_idle_clamp_threshold), 1200000);/* 50ms */ +			dev_dbg(adev->dev, "%s: configure vpe dpm pratio done!\n", __func__); +		} else { +			dev_dbg(adev->dev, "%s: invalid pratio parameters!\n", __func__); +			goto disable_dpm; +		} +	} +	return 0; + +disable_dpm: +	dpm_ctl = RREG32(vpe_get_reg_offset(vpe, 0, vpe->regs.dpm_enable)); +	dpm_ctl &= 0xfffffffe; /* Disable DPM */ +	WREG32(vpe_get_reg_offset(vpe, 0, vpe->regs.dpm_enable), dpm_ctl); +	dev_dbg(adev->dev, "%s: disable vpe dpm\n", __func__); +	return 0; +} +  int amdgpu_vpe_psp_update_sram(struct amdgpu_device *adev)  {  	struct amdgpu_firmware_info ucode = { @@ -134,6 +307,19 @@ static int vpe_early_init(void *handle)  	return 0;  } +static void vpe_idle_work_handler(struct work_struct *work) +{ +	struct amdgpu_device *adev = +		container_of(work, struct amdgpu_device, vpe.idle_work.work); +	unsigned int fences = 0; + +	fences += amdgpu_fence_count_emitted(&adev->vpe.ring); + +	if (fences == 0) +		amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VPE, AMD_PG_STATE_GATE); +	else +		schedule_delayed_work(&adev->vpe.idle_work, VPE_IDLE_TIMEOUT); +}  static int vpe_common_init(struct amdgpu_vpe *vpe)  { @@ -150,6 +336,9 @@ static int vpe_common_init(struct amdgpu_vpe *vpe)  		return r;  	} +	vpe->context_started = false; +	INIT_DELAYED_WORK(&adev->vpe.idle_work, vpe_idle_work_handler); +  	return 0;  } @@ -219,6 +408,9 @@ static int vpe_hw_fini(void *handle)  	vpe_ring_stop(vpe); +	/* Power off VPE */ +	amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VPE, AMD_PG_STATE_GATE); +  	return 0;  } @@ -226,6 +418,8 @@ static int vpe_suspend(void *handle)  {  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; +	cancel_delayed_work_sync(&adev->vpe.idle_work); +  	return vpe_hw_fini(adev);  } @@ -430,6 +624,21 @@ static int vpe_set_clockgating_state(void *handle,  static int vpe_set_powergating_state(void *handle,  				     enum amd_powergating_state state)  { +	struct amdgpu_device *adev = (struct amdgpu_device *)handle; +	struct amdgpu_vpe *vpe = &adev->vpe; + +	if (!adev->pm.dpm_enabled) +		dev_err(adev->dev, "Without PM, cannot support powergating\n"); + +	dev_dbg(adev->dev, "%s: %s!\n", __func__, (state == AMD_PG_STATE_GATE) ? "GATE":"UNGATE"); + +	if (state == AMD_PG_STATE_GATE) { +		amdgpu_dpm_enable_vpe(adev, false); +		vpe->context_started = false; +	} else { +		amdgpu_dpm_enable_vpe(adev, true); +	} +  	return 0;  } @@ -595,6 +804,38 @@ err0:  	return ret;  } +static void vpe_ring_begin_use(struct amdgpu_ring *ring) +{ +	struct amdgpu_device *adev = ring->adev; +	struct amdgpu_vpe *vpe = &adev->vpe; + +	cancel_delayed_work_sync(&adev->vpe.idle_work); + +	/* Power on VPE and notify VPE of new context  */ +	if (!vpe->context_started) { +		uint32_t context_notify; + +		/* Power on VPE */ +		amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VPE, AMD_PG_STATE_UNGATE); + +		/* Indicates that a job from a new context has been submitted. */ +		context_notify = RREG32(vpe_get_reg_offset(vpe, 0, vpe->regs.context_indicator)); +		if ((context_notify & 0x1) == 0) +			context_notify |= 0x1; +		else +			context_notify &= ~(0x1); +		WREG32(vpe_get_reg_offset(vpe, 0, vpe->regs.context_indicator), context_notify); +		vpe->context_started = true; +	} +} + +static void vpe_ring_end_use(struct amdgpu_ring *ring) +{ +	struct amdgpu_device *adev = ring->adev; + +	schedule_delayed_work(&adev->vpe.idle_work, VPE_IDLE_TIMEOUT); +} +  static const struct amdgpu_ring_funcs vpe_ring_funcs = {  	.type = AMDGPU_RING_TYPE_VPE,  	.align_mask = 0xf, @@ -625,6 +866,8 @@ static const struct amdgpu_ring_funcs vpe_ring_funcs = {  	.init_cond_exec = vpe_ring_init_cond_exec,  	.patch_cond_exec = vpe_ring_patch_cond_exec,  	.preempt_ib = vpe_ring_preempt_ib, +	.begin_use = vpe_ring_begin_use, +	.end_use = vpe_ring_end_use,  };  static void vpe_set_ring_funcs(struct amdgpu_device *adev) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.h index 29d56f7ae4a9..1153ddaea64d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.h @@ -47,6 +47,15 @@ struct vpe_regs {  	uint32_t queue0_rb_wptr_lo;  	uint32_t queue0_rb_wptr_hi;  	uint32_t queue0_preempt; + +	uint32_t dpm_enable; +	uint32_t dpm_pratio; +	uint32_t dpm_request_interval; +	uint32_t dpm_decision_threshold; +	uint32_t dpm_busy_clamp_threshold; +	uint32_t dpm_idle_clamp_threshold; +	uint32_t dpm_request_lv; +	uint32_t context_indicator;  };  struct amdgpu_vpe { @@ -63,12 +72,15 @@ struct amdgpu_vpe {  	struct amdgpu_bo		*cmdbuf_obj;  	uint64_t			cmdbuf_gpu_addr;  	uint32_t			*cmdbuf_cpu_addr; +	struct delayed_work		idle_work; +	bool				context_started;  };  int amdgpu_vpe_psp_update_sram(struct amdgpu_device *adev);  int amdgpu_vpe_init_microcode(struct amdgpu_vpe *vpe);  int amdgpu_vpe_ring_init(struct amdgpu_vpe *vpe);  int amdgpu_vpe_ring_fini(struct amdgpu_vpe *vpe); +int amdgpu_vpe_configure_dpm(struct amdgpu_vpe *vpe);  #define vpe_ring_init(vpe) ((vpe)->funcs->ring_init ? (vpe)->funcs->ring_init((vpe)) : 0)  #define vpe_ring_start(vpe) ((vpe)->funcs->ring_start ? (vpe)->funcs->ring_start((vpe)) : 0) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c index 08916538a615..8db880244324 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c @@ -221,8 +221,23 @@ static struct attribute *amdgpu_vram_mgr_attributes[] = {  	NULL  }; +static umode_t amdgpu_vram_attrs_is_visible(struct kobject *kobj, +					    struct attribute *attr, int i) +{ +	struct device *dev = kobj_to_dev(kobj); +	struct drm_device *ddev = dev_get_drvdata(dev); +	struct amdgpu_device *adev = drm_to_adev(ddev); + +	if (attr == &dev_attr_mem_info_vram_vendor.attr && +	    !adev->gmc.vram_vendor) +		return 0; + +	return attr->mode; +} +  const struct attribute_group amdgpu_vram_mgr_attr_group = { -	.attrs = amdgpu_vram_mgr_attributes +	.attrs = amdgpu_vram_mgr_attributes, +	.is_visible = amdgpu_vram_attrs_is_visible  };  /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c index bd20cb3b9819..a6c88f2fe6e5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c @@ -413,6 +413,38 @@ static ssize_t amdgpu_xgmi_show_num_links(struct device *dev,  	return sysfs_emit(buf, "%s\n", buf);  } +static ssize_t amdgpu_xgmi_show_connected_port_num(struct device *dev, +					struct device_attribute *attr, +					char *buf) +{ +	struct drm_device *ddev = dev_get_drvdata(dev); +	struct amdgpu_device *adev = drm_to_adev(ddev); +	struct psp_xgmi_topology_info *top = &adev->psp.xgmi_context.top_info; +	int i, j, size = 0; +	int current_node; +	/* +	 * get the node id in the sysfs for the current socket and show +	 * it in the port num info output in the sysfs for easy reading. +	 * it is NOT the one retrieved from xgmi ta. +	 */ +	for (i = 0; i < top->num_nodes; i++) { +		if (top->nodes[i].node_id == adev->gmc.xgmi.node_id) { +			current_node = i; +			break; +		} +	} + +	for (i = 0; i < top->num_nodes; i++) { +		for (j = 0; j < top->nodes[i].num_links; j++) +			/* node id in sysfs starts from 1 rather than 0 so +1 here */ +			size += sysfs_emit_at(buf, size, "%02x:%02x ->  %02x:%02x\n", current_node + 1, +					      top->nodes[i].port_num[j].src_xgmi_port_num, i + 1, +					      top->nodes[i].port_num[j].dst_xgmi_port_num); +	} + +	return size; +} +  #define AMDGPU_XGMI_SET_FICAA(o)	((o) | 0x456801)  static ssize_t amdgpu_xgmi_show_error(struct device *dev,  				      struct device_attribute *attr, @@ -452,6 +484,7 @@ static DEVICE_ATTR(xgmi_physical_id, 0444, amdgpu_xgmi_show_physical_id, NULL);  static DEVICE_ATTR(xgmi_error, S_IRUGO, amdgpu_xgmi_show_error, NULL);  static DEVICE_ATTR(xgmi_num_hops, S_IRUGO, amdgpu_xgmi_show_num_hops, NULL);  static DEVICE_ATTR(xgmi_num_links, S_IRUGO, amdgpu_xgmi_show_num_links, NULL); +static DEVICE_ATTR(xgmi_port_num, S_IRUGO, amdgpu_xgmi_show_connected_port_num, NULL);  static int amdgpu_xgmi_sysfs_add_dev_info(struct amdgpu_device *adev,  					 struct amdgpu_hive_info *hive) @@ -487,6 +520,13 @@ static int amdgpu_xgmi_sysfs_add_dev_info(struct amdgpu_device *adev,  	if (ret)  		pr_err("failed to create xgmi_num_links\n"); +	/* Create xgmi port num file if supported */ +	if (adev->psp.xgmi_context.xgmi_ta_caps & EXTEND_PEER_LINK_INFO_CMD_FLAG) { +		ret = device_create_file(adev->dev, &dev_attr_xgmi_port_num); +		if (ret) +			dev_err(adev->dev, "failed to create xgmi_port_num\n"); +	} +  	/* Create sysfs link to hive info folder on the first device */  	if (hive->kobj.parent != (&adev->dev->kobj)) {  		ret = sysfs_create_link(&adev->dev->kobj, &hive->kobj, @@ -517,6 +557,8 @@ remove_file:  	device_remove_file(adev->dev, &dev_attr_xgmi_error);  	device_remove_file(adev->dev, &dev_attr_xgmi_num_hops);  	device_remove_file(adev->dev, &dev_attr_xgmi_num_links); +	if (adev->psp.xgmi_context.xgmi_ta_caps & EXTEND_PEER_LINK_INFO_CMD_FLAG) +		device_remove_file(adev->dev, &dev_attr_xgmi_port_num);  success:  	return ret; @@ -533,6 +575,8 @@ static void amdgpu_xgmi_sysfs_rem_dev_info(struct amdgpu_device *adev,  	device_remove_file(adev->dev, &dev_attr_xgmi_error);  	device_remove_file(adev->dev, &dev_attr_xgmi_num_hops);  	device_remove_file(adev->dev, &dev_attr_xgmi_num_links); +	if (adev->psp.xgmi_context.xgmi_ta_caps & EXTEND_PEER_LINK_INFO_CMD_FLAG) +		device_remove_file(adev->dev, &dev_attr_xgmi_port_num);  	if (hive->kobj.parent != (&adev->dev->kobj))  		sysfs_remove_link(&adev->dev->kobj,"xgmi_hive_info"); @@ -779,6 +823,28 @@ static int amdgpu_xgmi_initialize_hive_get_data_partition(struct amdgpu_hive_inf  	return 0;  } +static void amdgpu_xgmi_fill_topology_info(struct amdgpu_device *adev, +	struct amdgpu_device *peer_adev) +{ +	struct psp_xgmi_topology_info *top_info = &adev->psp.xgmi_context.top_info; +	struct psp_xgmi_topology_info *peer_info = &peer_adev->psp.xgmi_context.top_info; + +	for (int i = 0; i < peer_info->num_nodes; i++) { +		if (peer_info->nodes[i].node_id == adev->gmc.xgmi.node_id) { +			for (int j = 0; j < top_info->num_nodes; j++) { +				if (top_info->nodes[j].node_id == peer_adev->gmc.xgmi.node_id) { +					peer_info->nodes[i].num_hops = top_info->nodes[j].num_hops; +					peer_info->nodes[i].is_sharing_enabled = +							top_info->nodes[j].is_sharing_enabled; +					peer_info->nodes[i].num_links = +							top_info->nodes[j].num_links; +					return; +				} +			} +		} +	} +} +  int amdgpu_xgmi_add_device(struct amdgpu_device *adev)  {  	struct psp_xgmi_topology_info *top_info; @@ -853,18 +919,38 @@ int amdgpu_xgmi_add_device(struct amdgpu_device *adev)  				goto exit_unlock;  		} -		/* get latest topology info for each device from psp */ -		list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) { -			ret = psp_xgmi_get_topology_info(&tmp_adev->psp, count, -					&tmp_adev->psp.xgmi_context.top_info, false); +		if (amdgpu_sriov_vf(adev) && +			adev->psp.xgmi_context.xgmi_ta_caps & EXTEND_PEER_LINK_INFO_CMD_FLAG) { +			/* only get topology for VF being init if it can support full duplex */ +			ret = psp_xgmi_get_topology_info(&adev->psp, count, +						&adev->psp.xgmi_context.top_info, false);  			if (ret) { -				dev_err(tmp_adev->dev, +				dev_err(adev->dev,  					"XGMI: Get topology failure on device %llx, hive %llx, ret %d", -					tmp_adev->gmc.xgmi.node_id, -					tmp_adev->gmc.xgmi.hive_id, ret); -				/* To do : continue with some node failed or disable the whole hive */ +					adev->gmc.xgmi.node_id, +					adev->gmc.xgmi.hive_id, ret); +				/* To do: continue with some node failed or disable the whole hive*/  				goto exit_unlock;  			} + +			/* fill the topology info for peers instead of getting from PSP */ +			list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) { +				amdgpu_xgmi_fill_topology_info(adev, tmp_adev); +			} +		} else { +			/* get latest topology info for each device from psp */ +			list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) { +				ret = psp_xgmi_get_topology_info(&tmp_adev->psp, count, +					&tmp_adev->psp.xgmi_context.top_info, false); +				if (ret) { +					dev_err(tmp_adev->dev, +						"XGMI: Get topology failure on device %llx, hive %llx, ret %d", +						tmp_adev->gmc.xgmi.node_id, +						tmp_adev->gmc.xgmi.hive_id, ret); +					/* To do : continue with some node failed or disable the whole hive */ +					goto exit_unlock; +				} +			}  		}  		/* get topology again for hives that support extended data */ @@ -1227,10 +1313,10 @@ static void __xgmi_v6_4_0_query_error_count(struct amdgpu_device *adev, struct a  	switch (xgmi_v6_4_0_pcs_mca_get_error_type(adev, status)) {  	case AMDGPU_MCA_ERROR_TYPE_UE: -		amdgpu_ras_error_statistic_ue_count(err_data, mcm_info, 1ULL); +		amdgpu_ras_error_statistic_ue_count(err_data, mcm_info, NULL, 1ULL);  		break;  	case AMDGPU_MCA_ERROR_TYPE_CE: -		amdgpu_ras_error_statistic_ce_count(err_data, mcm_info, 1ULL); +		amdgpu_ras_error_statistic_ce_count(err_data, mcm_info, NULL, 1ULL);  		break;  	default:  		break; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h index 6cab882e8061..1592c63b3099 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h @@ -43,7 +43,6 @@ struct amdgpu_hive_info {  	} pstate;  	struct amdgpu_reset_domain *reset_domain; -	uint32_t device_remove_count;  	atomic_t ras_recovery;  }; diff --git a/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c b/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c index 3f715e7fe1a9..d6f808acfb17 100644 --- a/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c +++ b/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c @@ -24,6 +24,7 @@  #include "soc15.h"  #include "soc15_common.h" +#include "amdgpu_reg_state.h"  #include "amdgpu_xcp.h"  #include "gfx_v9_4_3.h"  #include "gfxhub_v1_2.h" @@ -656,3 +657,416 @@ int aqua_vanjaram_init_soc_config(struct amdgpu_device *adev)  	return 0;  } + +static void aqua_read_smn(struct amdgpu_device *adev, +			  struct amdgpu_smn_reg_data *regdata, +			  uint64_t smn_addr) +{ +	regdata->addr = smn_addr; +	regdata->value = RREG32_PCIE(smn_addr); +} + +struct aqua_reg_list { +	uint64_t start_addr; +	uint32_t num_regs; +	uint32_t incrx; +}; + +#define DW_ADDR_INCR	4 + +static void aqua_read_smn_ext(struct amdgpu_device *adev, +			      struct amdgpu_smn_reg_data *regdata, +			      uint64_t smn_addr, int i) +{ +	regdata->addr = +		smn_addr + adev->asic_funcs->encode_ext_smn_addressing(i); +	regdata->value = RREG32_PCIE_EXT(regdata->addr); +} + +#define smnreg_0x1A340218	0x1A340218 +#define smnreg_0x1A3402E4	0x1A3402E4 +#define smnreg_0x1A340294	0x1A340294 +#define smreg_0x1A380088	0x1A380088 + +#define NUM_PCIE_SMN_REGS	14 + +static struct aqua_reg_list pcie_reg_addrs[] = { +	{ smnreg_0x1A340218, 1, 0 }, +	{ smnreg_0x1A3402E4, 1, 0 }, +	{ smnreg_0x1A340294, 6, DW_ADDR_INCR }, +	{ smreg_0x1A380088, 6, DW_ADDR_INCR }, +}; + +static ssize_t aqua_vanjaram_read_pcie_state(struct amdgpu_device *adev, +					     void *buf, size_t max_size) +{ +	struct amdgpu_reg_state_pcie_v1_0 *pcie_reg_state; +	uint32_t start_addr, incrx, num_regs, szbuf; +	struct amdgpu_regs_pcie_v1_0 *pcie_regs; +	struct amdgpu_smn_reg_data *reg_data; +	struct pci_dev *us_pdev, *ds_pdev; +	int aer_cap, r, n; + +	if (!buf || !max_size) +		return -EINVAL; + +	pcie_reg_state = (struct amdgpu_reg_state_pcie_v1_0 *)buf; + +	szbuf = sizeof(*pcie_reg_state) + +		amdgpu_reginst_size(1, sizeof(*pcie_regs), NUM_PCIE_SMN_REGS); +	/* Only one instance of pcie regs */ +	if (max_size < szbuf) +		return -EOVERFLOW; + +	pcie_regs = (struct amdgpu_regs_pcie_v1_0 *)((uint8_t *)buf + +						     sizeof(*pcie_reg_state)); +	pcie_regs->inst_header.instance = 0; +	pcie_regs->inst_header.state = AMDGPU_INST_S_OK; +	pcie_regs->inst_header.num_smn_regs = NUM_PCIE_SMN_REGS; + +	reg_data = pcie_regs->smn_reg_values; + +	for (r = 0; r < ARRAY_SIZE(pcie_reg_addrs); r++) { +		start_addr = pcie_reg_addrs[r].start_addr; +		incrx = pcie_reg_addrs[r].incrx; +		num_regs = pcie_reg_addrs[r].num_regs; +		for (n = 0; n < num_regs; n++) { +			aqua_read_smn(adev, reg_data, start_addr + n * incrx); +			++reg_data; +		} +	} + +	ds_pdev = pci_upstream_bridge(adev->pdev); +	us_pdev = pci_upstream_bridge(ds_pdev); + +	pcie_capability_read_word(us_pdev, PCI_EXP_DEVSTA, +				  &pcie_regs->device_status); +	pcie_capability_read_word(us_pdev, PCI_EXP_LNKSTA, +				  &pcie_regs->link_status); + +	aer_cap = pci_find_ext_capability(us_pdev, PCI_EXT_CAP_ID_ERR); +	if (aer_cap) { +		pci_read_config_dword(us_pdev, aer_cap + PCI_ERR_COR_STATUS, +				      &pcie_regs->pcie_corr_err_status); +		pci_read_config_dword(us_pdev, aer_cap + PCI_ERR_UNCOR_STATUS, +				      &pcie_regs->pcie_uncorr_err_status); +	} + +	pci_read_config_dword(us_pdev, PCI_PRIMARY_BUS, +			      &pcie_regs->sub_bus_number_latency); + +	pcie_reg_state->common_header.structure_size = szbuf; +	pcie_reg_state->common_header.format_revision = 1; +	pcie_reg_state->common_header.content_revision = 0; +	pcie_reg_state->common_header.state_type = AMDGPU_REG_STATE_TYPE_PCIE; +	pcie_reg_state->common_header.num_instances = 1; + +	return pcie_reg_state->common_header.structure_size; +} + +#define smnreg_0x11A00050	0x11A00050 +#define smnreg_0x11A00180	0x11A00180 +#define smnreg_0x11A00070	0x11A00070 +#define smnreg_0x11A00200	0x11A00200 +#define smnreg_0x11A0020C	0x11A0020C +#define smnreg_0x11A00210	0x11A00210 +#define smnreg_0x11A00108	0x11A00108 + +#define XGMI_LINK_REG(smnreg, l) ((smnreg) | (l << 20)) + +#define NUM_XGMI_SMN_REGS 25 + +static struct aqua_reg_list xgmi_reg_addrs[] = { +	{ smnreg_0x11A00050, 1, 0 }, +	{ smnreg_0x11A00180, 16, DW_ADDR_INCR }, +	{ smnreg_0x11A00070, 4, DW_ADDR_INCR }, +	{ smnreg_0x11A00200, 1, 0 }, +	{ smnreg_0x11A0020C, 1, 0 }, +	{ smnreg_0x11A00210, 1, 0 }, +	{ smnreg_0x11A00108, 1, 0 }, +}; + +static ssize_t aqua_vanjaram_read_xgmi_state(struct amdgpu_device *adev, +					     void *buf, size_t max_size) +{ +	struct amdgpu_reg_state_xgmi_v1_0 *xgmi_reg_state; +	uint32_t start_addr, incrx, num_regs, szbuf; +	struct amdgpu_regs_xgmi_v1_0 *xgmi_regs; +	struct amdgpu_smn_reg_data *reg_data; +	const int max_xgmi_instances = 8; +	int inst = 0, i, j, r, n; +	const int xgmi_inst = 2; +	void *p; + +	if (!buf || !max_size) +		return -EINVAL; + +	xgmi_reg_state = (struct amdgpu_reg_state_xgmi_v1_0 *)buf; + +	szbuf = sizeof(*xgmi_reg_state) + +		amdgpu_reginst_size(max_xgmi_instances, sizeof(*xgmi_regs), +				    NUM_XGMI_SMN_REGS); +	/* Only one instance of pcie regs */ +	if (max_size < szbuf) +		return -EOVERFLOW; + +	p = &xgmi_reg_state->xgmi_state_regs[0]; +	for_each_inst(i, adev->aid_mask) { +		for (j = 0; j < xgmi_inst; ++j) { +			xgmi_regs = (struct amdgpu_regs_xgmi_v1_0 *)p; +			xgmi_regs->inst_header.instance = inst++; + +			xgmi_regs->inst_header.state = AMDGPU_INST_S_OK; +			xgmi_regs->inst_header.num_smn_regs = NUM_XGMI_SMN_REGS; + +			reg_data = xgmi_regs->smn_reg_values; + +			for (r = 0; r < ARRAY_SIZE(xgmi_reg_addrs); r++) { +				start_addr = xgmi_reg_addrs[r].start_addr; +				incrx = xgmi_reg_addrs[r].incrx; +				num_regs = xgmi_reg_addrs[r].num_regs; + +				for (n = 0; n < num_regs; n++) { +					aqua_read_smn_ext( +						adev, reg_data, +						XGMI_LINK_REG(start_addr, j) + +							n * incrx, +						i); +					++reg_data; +				} +			} +			p = reg_data; +		} +	} + +	xgmi_reg_state->common_header.structure_size = szbuf; +	xgmi_reg_state->common_header.format_revision = 1; +	xgmi_reg_state->common_header.content_revision = 0; +	xgmi_reg_state->common_header.state_type = AMDGPU_REG_STATE_TYPE_XGMI; +	xgmi_reg_state->common_header.num_instances = max_xgmi_instances; + +	return xgmi_reg_state->common_header.structure_size; +} + +#define smnreg_0x11C00070	0x11C00070 +#define smnreg_0x11C00210	0x11C00210 + +static struct aqua_reg_list wafl_reg_addrs[] = { +	{ smnreg_0x11C00070, 4, DW_ADDR_INCR }, +	{ smnreg_0x11C00210, 1, 0 }, +}; + +#define WAFL_LINK_REG(smnreg, l) ((smnreg) | (l << 20)) + +#define NUM_WAFL_SMN_REGS 5 + +static ssize_t aqua_vanjaram_read_wafl_state(struct amdgpu_device *adev, +					     void *buf, size_t max_size) +{ +	struct amdgpu_reg_state_wafl_v1_0 *wafl_reg_state; +	uint32_t start_addr, incrx, num_regs, szbuf; +	struct amdgpu_regs_wafl_v1_0 *wafl_regs; +	struct amdgpu_smn_reg_data *reg_data; +	const int max_wafl_instances = 8; +	int inst = 0, i, j, r, n; +	const int wafl_inst = 2; +	void *p; + +	if (!buf || !max_size) +		return -EINVAL; + +	wafl_reg_state = (struct amdgpu_reg_state_wafl_v1_0 *)buf; + +	szbuf = sizeof(*wafl_reg_state) + +		amdgpu_reginst_size(max_wafl_instances, sizeof(*wafl_regs), +				    NUM_WAFL_SMN_REGS); + +	if (max_size < szbuf) +		return -EOVERFLOW; + +	p = &wafl_reg_state->wafl_state_regs[0]; +	for_each_inst(i, adev->aid_mask) { +		for (j = 0; j < wafl_inst; ++j) { +			wafl_regs = (struct amdgpu_regs_wafl_v1_0 *)p; +			wafl_regs->inst_header.instance = inst++; + +			wafl_regs->inst_header.state = AMDGPU_INST_S_OK; +			wafl_regs->inst_header.num_smn_regs = NUM_WAFL_SMN_REGS; + +			reg_data = wafl_regs->smn_reg_values; + +			for (r = 0; r < ARRAY_SIZE(wafl_reg_addrs); r++) { +				start_addr = wafl_reg_addrs[r].start_addr; +				incrx = wafl_reg_addrs[r].incrx; +				num_regs = wafl_reg_addrs[r].num_regs; +				for (n = 0; n < num_regs; n++) { +					aqua_read_smn_ext( +						adev, reg_data, +						WAFL_LINK_REG(start_addr, j) + +							n * incrx, +						i); +					++reg_data; +				} +			} +			p = reg_data; +		} +	} + +	wafl_reg_state->common_header.structure_size = szbuf; +	wafl_reg_state->common_header.format_revision = 1; +	wafl_reg_state->common_header.content_revision = 0; +	wafl_reg_state->common_header.state_type = AMDGPU_REG_STATE_TYPE_WAFL; +	wafl_reg_state->common_header.num_instances = max_wafl_instances; + +	return wafl_reg_state->common_header.structure_size; +} + +#define smnreg_0x1B311060 0x1B311060 +#define smnreg_0x1B411060 0x1B411060 +#define smnreg_0x1B511060 0x1B511060 +#define smnreg_0x1B611060 0x1B611060 + +#define smnreg_0x1C307120 0x1C307120 +#define smnreg_0x1C317120 0x1C317120 + +#define smnreg_0x1C320830 0x1C320830 +#define smnreg_0x1C380830 0x1C380830 +#define smnreg_0x1C3D0830 0x1C3D0830 +#define smnreg_0x1C420830 0x1C420830 + +#define smnreg_0x1C320100 0x1C320100 +#define smnreg_0x1C380100 0x1C380100 +#define smnreg_0x1C3D0100 0x1C3D0100 +#define smnreg_0x1C420100 0x1C420100 + +#define smnreg_0x1B310500 0x1B310500 +#define smnreg_0x1C300400 0x1C300400 + +#define USR_CAKE_INCR 0x11000 +#define USR_LINK_INCR 0x100000 +#define USR_CP_INCR 0x10000 + +#define NUM_USR_SMN_REGS	20 + +struct aqua_reg_list usr_reg_addrs[] = { +	{ smnreg_0x1B311060, 4, DW_ADDR_INCR }, +	{ smnreg_0x1B411060, 4, DW_ADDR_INCR }, +	{ smnreg_0x1B511060, 4, DW_ADDR_INCR }, +	{ smnreg_0x1B611060, 4, DW_ADDR_INCR }, +	{ smnreg_0x1C307120, 2, DW_ADDR_INCR }, +	{ smnreg_0x1C317120, 2, DW_ADDR_INCR }, +}; + +#define NUM_USR1_SMN_REGS	46 +struct aqua_reg_list usr1_reg_addrs[] = { +	{ smnreg_0x1C320830, 6, USR_CAKE_INCR }, +	{ smnreg_0x1C380830, 5, USR_CAKE_INCR }, +	{ smnreg_0x1C3D0830, 5, USR_CAKE_INCR }, +	{ smnreg_0x1C420830, 4, USR_CAKE_INCR }, +	{ smnreg_0x1C320100, 6, USR_CAKE_INCR }, +	{ smnreg_0x1C380100, 5, USR_CAKE_INCR }, +	{ smnreg_0x1C3D0100, 5, USR_CAKE_INCR }, +	{ smnreg_0x1C420100, 4, USR_CAKE_INCR }, +	{ smnreg_0x1B310500, 4, USR_LINK_INCR }, +	{ smnreg_0x1C300400, 2, USR_CP_INCR }, +}; + +static ssize_t aqua_vanjaram_read_usr_state(struct amdgpu_device *adev, +					    void *buf, size_t max_size, +					    int reg_state) +{ +	uint32_t start_addr, incrx, num_regs, szbuf, num_smn; +	struct amdgpu_reg_state_usr_v1_0 *usr_reg_state; +	struct amdgpu_regs_usr_v1_0 *usr_regs; +	struct amdgpu_smn_reg_data *reg_data; +	const int max_usr_instances = 4; +	struct aqua_reg_list *reg_addrs; +	int inst = 0, i, n, r, arr_size; +	void *p; + +	if (!buf || !max_size) +		return -EINVAL; + +	switch (reg_state) { +	case AMDGPU_REG_STATE_TYPE_USR: +		arr_size = ARRAY_SIZE(usr_reg_addrs); +		reg_addrs = usr_reg_addrs; +		num_smn = NUM_USR_SMN_REGS; +		break; +	case AMDGPU_REG_STATE_TYPE_USR_1: +		arr_size = ARRAY_SIZE(usr1_reg_addrs); +		reg_addrs = usr1_reg_addrs; +		num_smn = NUM_USR1_SMN_REGS; +		break; +	default: +		return -EINVAL; +	} + +	usr_reg_state = (struct amdgpu_reg_state_usr_v1_0 *)buf; + +	szbuf = sizeof(*usr_reg_state) + amdgpu_reginst_size(max_usr_instances, +							     sizeof(*usr_regs), +							     num_smn); +	if (max_size < szbuf) +		return -EOVERFLOW; + +	p = &usr_reg_state->usr_state_regs[0]; +	for_each_inst(i, adev->aid_mask) { +		usr_regs = (struct amdgpu_regs_usr_v1_0 *)p; +		usr_regs->inst_header.instance = inst++; +		usr_regs->inst_header.state = AMDGPU_INST_S_OK; +		usr_regs->inst_header.num_smn_regs = num_smn; +		reg_data = usr_regs->smn_reg_values; + +		for (r = 0; r < arr_size; r++) { +			start_addr = reg_addrs[r].start_addr; +			incrx = reg_addrs[r].incrx; +			num_regs = reg_addrs[r].num_regs; +			for (n = 0; n < num_regs; n++) { +				aqua_read_smn_ext(adev, reg_data, +						  start_addr + n * incrx, i); +				reg_data++; +			} +		} +		p = reg_data; +	} + +	usr_reg_state->common_header.structure_size = szbuf; +	usr_reg_state->common_header.format_revision = 1; +	usr_reg_state->common_header.content_revision = 0; +	usr_reg_state->common_header.state_type = AMDGPU_REG_STATE_TYPE_USR; +	usr_reg_state->common_header.num_instances = max_usr_instances; + +	return usr_reg_state->common_header.structure_size; +} + +ssize_t aqua_vanjaram_get_reg_state(struct amdgpu_device *adev, +				    enum amdgpu_reg_state reg_state, void *buf, +				    size_t max_size) +{ +	ssize_t size; + +	switch (reg_state) { +	case AMDGPU_REG_STATE_TYPE_PCIE: +		size = aqua_vanjaram_read_pcie_state(adev, buf, max_size); +		break; +	case AMDGPU_REG_STATE_TYPE_XGMI: +		size = aqua_vanjaram_read_xgmi_state(adev, buf, max_size); +		break; +	case AMDGPU_REG_STATE_TYPE_WAFL: +		size = aqua_vanjaram_read_wafl_state(adev, buf, max_size); +		break; +	case AMDGPU_REG_STATE_TYPE_USR: +		size = aqua_vanjaram_read_usr_state(adev, buf, max_size, +						    AMDGPU_REG_STATE_TYPE_USR); +		break; +	case AMDGPU_REG_STATE_TYPE_USR_1: +		size = aqua_vanjaram_read_usr_state( +			adev, buf, max_size, AMDGPU_REG_STATE_TYPE_USR_1); +		break; +	default: +		return -EINVAL; +	} + +	return size; +} diff --git a/drivers/gpu/drm/amd/amdgpu/athub_v3_0.c b/drivers/gpu/drm/amd/amdgpu/athub_v3_0.c index f0737fb3a999..d1bba9c64e16 100644 --- a/drivers/gpu/drm/amd/amdgpu/athub_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/athub_v3_0.c @@ -30,6 +30,8 @@  #define regATHUB_MISC_CNTL_V3_0_1			0x00d7  #define regATHUB_MISC_CNTL_V3_0_1_BASE_IDX		0 +#define regATHUB_MISC_CNTL_V3_3_0			0x00d8 +#define regATHUB_MISC_CNTL_V3_3_0_BASE_IDX		0  static uint32_t athub_v3_0_get_cg_cntl(struct amdgpu_device *adev) @@ -40,6 +42,9 @@ static uint32_t athub_v3_0_get_cg_cntl(struct amdgpu_device *adev)  	case IP_VERSION(3, 0, 1):  		data = RREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL_V3_0_1);  		break; +	case IP_VERSION(3, 3, 0): +		data = RREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL_V3_3_0); +		break;  	default:  		data = RREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL);  		break; @@ -53,6 +58,9 @@ static void athub_v3_0_set_cg_cntl(struct amdgpu_device *adev, uint32_t data)  	case IP_VERSION(3, 0, 1):  		WREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL_V3_0_1, data);  		break; +	case IP_VERSION(3, 3, 0): +		WREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL_V3_3_0, data); +		break;  	default:  		WREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL, data);  		break; diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c index 2c221000782c..a33e890c70d9 100644 --- a/drivers/gpu/drm/amd/amdgpu/atom.c +++ b/drivers/gpu/drm/amd/amdgpu/atom.c @@ -395,7 +395,6 @@ static void atom_skip_src_int(atom_exec_context *ctx, uint8_t attr, int *ptr)  			(*ptr)++;  			return;  		} -		return;  	}  } diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c index 3ee219aa2891..7672abe6c140 100644 --- a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c +++ b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c @@ -28,6 +28,7 @@  #include <acpi/video.h> +#include <drm/drm_edid.h>  #include <drm/amdgpu_drm.h>  #include "amdgpu.h"  #include "amdgpu_connectors.h" diff --git a/drivers/gpu/drm/amd/amdgpu/cik_ih.c b/drivers/gpu/drm/amd/amdgpu/cik_ih.c index 6f7c031dd197..f24e34dc33d1 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_ih.c @@ -204,6 +204,12 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev,  		tmp = RREG32(mmIH_RB_CNTL);  		tmp |= IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK;  		WREG32(mmIH_RB_CNTL, tmp); + +		/* Unset the CLEAR_OVERFLOW bit immediately so new overflows +		 * can be detected. +		 */ +		tmp &= ~IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK; +		WREG32(mmIH_RB_CNTL, tmp);  	}  	return (wptr & ih->ptr_mask);  } diff --git a/drivers/gpu/drm/amd/amdgpu/cz_ih.c b/drivers/gpu/drm/amd/amdgpu/cz_ih.c index b8c47e0cf37a..c19681492efa 100644 --- a/drivers/gpu/drm/amd/amdgpu/cz_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/cz_ih.c @@ -216,6 +216,11 @@ static u32 cz_ih_get_wptr(struct amdgpu_device *adev,  	tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);  	WREG32(mmIH_RB_CNTL, tmp); +	/* Unset the CLEAR_OVERFLOW bit immediately so new overflows +	 * can be detected. +	 */ +	tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); +	WREG32(mmIH_RB_CNTL, tmp);  out:  	return (wptr & ih->ptr_mask); diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index bb666cb7522e..587ee632a3b8 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c @@ -21,6 +21,7 @@   *   */ +#include <drm/drm_edid.h>  #include <drm/drm_fourcc.h>  #include <drm/drm_modeset_helper.h>  #include <drm/drm_modeset_helper_vtables.h> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index 7af277f61cca..f22ec27365bd 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c @@ -21,6 +21,7 @@   *   */ +#include <drm/drm_edid.h>  #include <drm/drm_fourcc.h>  #include <drm/drm_modeset_helper.h>  #include <drm/drm_modeset_helper_vtables.h> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c index 143efc37a17f..4dbe9b3259b5 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c @@ -23,6 +23,7 @@  #include <linux/pci.h> +#include <drm/drm_edid.h>  #include <drm/drm_fourcc.h>  #include <drm/drm_modeset_helper.h>  #include <drm/drm_modeset_helper_vtables.h> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index adeddfb7ff12..05bcce23385e 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c @@ -21,6 +21,7 @@   *   */ +#include <drm/drm_edid.h>  #include <drm/drm_fourcc.h>  #include <drm/drm_modeset_helper.h>  #include <drm/drm_modeset_helper_vtables.h> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c index c8a3bf01743f..dcdecb18b230 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c @@ -3996,16 +3996,13 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)  	if (!amdgpu_sriov_vf(adev)) {  		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", ucode_prefix); -		err = amdgpu_ucode_request(adev, &adev->gfx.rlc_fw, fw_name); -		/* don't check this.  There are apparently firmwares in the wild with -		 * incorrect size in the header -		 */ -		if (err == -ENODEV) -			goto out; +		err = request_firmware(&adev->gfx.rlc_fw, fw_name, adev->dev);  		if (err) -			dev_dbg(adev->dev, -				"gfx10: amdgpu_ucode_request() failed \"%s\"\n", -				fw_name); +			goto out; + +		/* don't validate this firmware. There are apparently firmwares +		 * in the wild with incorrect size in the header +		 */  		rlc_hdr = (const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data;  		version_major = le16_to_cpu(rlc_hdr->header.header_version_major);  		version_minor = le16_to_cpu(rlc_hdr->header.header_version_minor); @@ -4030,8 +4027,6 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)  		err = 0;  		adev->gfx.mec2_fw = NULL;  	} -	amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC2); -	amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC2_JT);  	gfx_v10_0_check_fw_write_wait(adev);  out: @@ -6592,8 +6587,9 @@ static int gfx_v10_0_compute_mqd_init(struct amdgpu_device *adev, void *m,  #ifdef __BIG_ENDIAN  	tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, ENDIAN_SWAP, 1);  #endif -	tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, UNORD_DISPATCH, 0); -	tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TUNNEL_DISPATCH, 0); +	tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, UNORD_DISPATCH, 1); +	tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TUNNEL_DISPATCH, +			    prop->allow_tunneling);  	tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, PRIV_STATE, 1);  	tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, KMD_QUEUE, 1);  	mqd->cp_hqd_pq_control = tmp; diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c index 8ed4a6fb147a..4f3bfdc75b37 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -67,6 +67,7 @@ MODULE_FIRMWARE("amdgpu/gc_11_0_0_pfp.bin");  MODULE_FIRMWARE("amdgpu/gc_11_0_0_me.bin");  MODULE_FIRMWARE("amdgpu/gc_11_0_0_mec.bin");  MODULE_FIRMWARE("amdgpu/gc_11_0_0_rlc.bin"); +MODULE_FIRMWARE("amdgpu/gc_11_0_0_rlc_1.bin");  MODULE_FIRMWARE("amdgpu/gc_11_0_0_toc.bin");  MODULE_FIRMWARE("amdgpu/gc_11_0_1_pfp.bin");  MODULE_FIRMWARE("amdgpu/gc_11_0_1_me.bin"); @@ -106,23 +107,6 @@ static const struct soc15_reg_golden golden_settings_gc_11_0_1[] =  	SOC15_REG_GOLDEN_VALUE(GC, 0, regTCP_CNTL2, 0xfcffffff, 0x0000000a)  }; -static const struct soc15_reg_golden golden_settings_gc_11_5_0[] = { -	SOC15_REG_GOLDEN_VALUE(GC, 0, regDB_DEBUG5, 0xffffffff, 0x00000800), -	SOC15_REG_GOLDEN_VALUE(GC, 0, regGB_ADDR_CONFIG, 0x0c1807ff, 0x00000242), -	SOC15_REG_GOLDEN_VALUE(GC, 0, regGCR_GENERAL_CNTL, 0x1ff1ffff, 0x00000500), -	SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2A_ADDR_MATCH_MASK, 0xffffffff, 0xfffffff3), -	SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2C_ADDR_MATCH_MASK, 0xffffffff, 0xfffffff3), -	SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2C_CTRL, 0xffffffff, 0xf37fff3f), -	SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2C_CTRL3, 0xfffffffb, 0x00f40188), -	SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2C_CTRL4, 0xf0ffffff, 0x8000b007), -	SOC15_REG_GOLDEN_VALUE(GC, 0, regPA_CL_ENHANCE, 0xf1ffffff, 0x00880007), -	SOC15_REG_GOLDEN_VALUE(GC, 0, regPC_CONFIG_CNTL_1, 0xffffffff, 0x00010000), -	SOC15_REG_GOLDEN_VALUE(GC, 0, regTA_CNTL_AUX, 0xf7f7ffff, 0x01030000), -	SOC15_REG_GOLDEN_VALUE(GC, 0, regTA_CNTL2, 0x007f0000, 0x00000000), -	SOC15_REG_GOLDEN_VALUE(GC, 0, regTCP_CNTL2, 0xffcfffff, 0x0000200a), -	SOC15_REG_GOLDEN_VALUE(GC, 0, regUTCL1_CTRL_2, 0xffffffff, 0x0000048f) -}; -  #define DEFAULT_SH_MEM_CONFIG \  	((SH_MEM_ADDRESS_MODE_64 << SH_MEM_CONFIG__ADDRESS_MODE__SHIFT) | \  	 (SH_MEM_ALIGNMENT_MODE_UNALIGNED << SH_MEM_CONFIG__ALIGNMENT_MODE__SHIFT) | \ @@ -293,6 +277,9 @@ static void gfx_v11_0_set_kiq_pm4_funcs(struct amdgpu_device *adev)  static void gfx_v11_0_init_golden_registers(struct amdgpu_device *adev)  { +	if (amdgpu_sriov_vf(adev)) +		return; +  	switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {  	case IP_VERSION(11, 0, 1):  	case IP_VERSION(11, 0, 4): @@ -300,11 +287,6 @@ static void gfx_v11_0_init_golden_registers(struct amdgpu_device *adev)  						golden_settings_gc_11_0_1,  						(const u32)ARRAY_SIZE(golden_settings_gc_11_0_1));  		break; -	case IP_VERSION(11, 5, 0): -		soc15_program_register_sequence(adev, -						golden_settings_gc_11_5_0, -						(const u32)ARRAY_SIZE(golden_settings_gc_11_5_0)); -		break;  	default:  		break;  	} @@ -564,7 +546,11 @@ static int gfx_v11_0_init_microcode(struct amdgpu_device *adev)  	}  	if (!amdgpu_sriov_vf(adev)) { -		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", ucode_prefix); +		if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(11, 0, 0) && +		    adev->pdev->revision == 0xCE) +			snprintf(fw_name, sizeof(fw_name), "amdgpu/gc_11_0_0_rlc_1.bin"); +		else +			snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", ucode_prefix);  		err = amdgpu_ucode_request(adev, &adev->gfx.rlc_fw, fw_name);  		if (err)  			goto out; @@ -3838,8 +3824,9 @@ static int gfx_v11_0_compute_mqd_init(struct amdgpu_device *adev, void *m,  			    (order_base_2(prop->queue_size / 4) - 1));  	tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, RPTR_BLOCK_SIZE,  			    (order_base_2(AMDGPU_GPU_PAGE_SIZE / 4) - 1)); -	tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, UNORD_DISPATCH, 0); -	tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TUNNEL_DISPATCH, 0); +	tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, UNORD_DISPATCH, 1); +	tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TUNNEL_DISPATCH, +			    prop->allow_tunneling);  	tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, PRIV_STATE, 1);  	tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, KMD_QUEUE, 1);  	mqd->cp_hqd_pq_control = tmp; @@ -4465,11 +4452,43 @@ static int gfx_v11_0_wait_for_idle(void *handle)  	return -ETIMEDOUT;  } +static int gfx_v11_0_request_gfx_index_mutex(struct amdgpu_device *adev, +					     int req) +{ +	u32 i, tmp, val; + +	for (i = 0; i < adev->usec_timeout; i++) { +		/* Request with MeId=2, PipeId=0 */ +		tmp = REG_SET_FIELD(0, CP_GFX_INDEX_MUTEX, REQUEST, req); +		tmp = REG_SET_FIELD(tmp, CP_GFX_INDEX_MUTEX, CLIENTID, 4); +		WREG32_SOC15(GC, 0, regCP_GFX_INDEX_MUTEX, tmp); + +		val = RREG32_SOC15(GC, 0, regCP_GFX_INDEX_MUTEX); +		if (req) { +			if (val == tmp) +				break; +		} else { +			tmp = REG_SET_FIELD(tmp, CP_GFX_INDEX_MUTEX, +					    REQUEST, 1); + +			/* unlocked or locked by firmware */ +			if (val != tmp) +				break; +		} +		udelay(1); +	} + +	if (i >= adev->usec_timeout) +		return -EINVAL; + +	return 0; +} +  static int gfx_v11_0_soft_reset(void *handle)  {  	u32 grbm_soft_reset = 0;  	u32 tmp; -	int i, j, k; +	int r, i, j, k;  	struct amdgpu_device *adev = (struct amdgpu_device *)handle;  	tmp = RREG32_SOC15(GC, 0, regCP_INT_CNTL); @@ -4509,6 +4528,13 @@ static int gfx_v11_0_soft_reset(void *handle)  		}  	} +	/* Try to acquire the gfx mutex before access to CP_VMID_RESET */ +	r = gfx_v11_0_request_gfx_index_mutex(adev, 1); +	if (r) { +		DRM_ERROR("Failed to acquire the gfx mutex during soft reset\n"); +		return r; +	} +  	WREG32_SOC15(GC, 0, regCP_VMID_RESET, 0xfffffffe);  	// Read CP_VMID_RESET register three times. @@ -4517,6 +4543,13 @@ static int gfx_v11_0_soft_reset(void *handle)  	RREG32_SOC15(GC, 0, regCP_VMID_RESET);  	RREG32_SOC15(GC, 0, regCP_VMID_RESET); +	/* release the gfx mutex */ +	r = gfx_v11_0_request_gfx_index_mutex(adev, 0); +	if (r) { +		DRM_ERROR("Failed to release the gfx mutex during soft reset\n"); +		return r; +	} +  	for (i = 0; i < adev->usec_timeout; i++) {  		if (!RREG32_SOC15(GC, 0, regCP_HQD_ACTIVE) &&  		    !RREG32_SOC15(GC, 0, regCP_GFX_HQD_ACTIVE)) @@ -6328,6 +6361,9 @@ static int gfx_v11_0_get_cu_info(struct amdgpu_device *adev,  	mutex_lock(&adev->grbm_idx_mutex);  	for (i = 0; i < adev->gfx.config.max_shader_engines; i++) {  		for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) { +			bitmap = i * adev->gfx.config.max_sh_per_se + j; +			if (!((gfx_v11_0_get_sa_active_bitmap(adev) >> bitmap) & 1)) +				continue;  			mask = 1;  			counter = 0;  			gfx_v11_0_select_se_sh(adev, i, j, 0xffffffff, 0); diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c index 4a09cc0d8ce0..131cddbdda0d 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c @@ -3828,8 +3828,8 @@ static void gfx_v9_4_3_inst_query_ras_err_count(struct amdgpu_device *adev,  	/* the caller should make sure initialize value of  	 * err_data->ue_count and err_data->ce_count  	 */ -	amdgpu_ras_error_statistic_ue_count(err_data, &mcm_info, ue_count); -	amdgpu_ras_error_statistic_ce_count(err_data, &mcm_info, ce_count); +	amdgpu_ras_error_statistic_ue_count(err_data, &mcm_info, NULL, ue_count); +	amdgpu_ras_error_statistic_ce_count(err_data, &mcm_info, NULL, ce_count);  }  static void gfx_v9_4_3_inst_reset_ras_err_count(struct amdgpu_device *adev, @@ -3882,150 +3882,6 @@ static void gfx_v9_4_3_inst_reset_ras_err_count(struct amdgpu_device *adev,  	mutex_unlock(&adev->grbm_idx_mutex);  } -static void gfx_v9_4_3_inst_query_utc_err_status(struct amdgpu_device *adev, -					int xcc_id) -{ -	uint32_t data; - -	data = RREG32_SOC15(GC, GET_INST(GC, xcc_id), regUTCL2_MEM_ECC_STATUS); -	if (data) { -		dev_warn(adev->dev, "GFX UTCL2 Mem Ecc Status: 0x%x!\n", data); -		WREG32_SOC15(GC, GET_INST(GC, xcc_id), regUTCL2_MEM_ECC_STATUS, 0x3); -	} - -	data = RREG32_SOC15(GC, GET_INST(GC, xcc_id), regVML2_MEM_ECC_STATUS); -	if (data) { -		dev_warn(adev->dev, "GFX VML2 Mem Ecc Status: 0x%x!\n", data); -		WREG32_SOC15(GC, GET_INST(GC, xcc_id), regVML2_MEM_ECC_STATUS, 0x3); -	} - -	data = RREG32_SOC15(GC, GET_INST(GC, xcc_id), -				regVML2_WALKER_MEM_ECC_STATUS); -	if (data) { -		dev_warn(adev->dev, "GFX VML2 Walker Mem Ecc Status: 0x%x!\n", data); -		WREG32_SOC15(GC, GET_INST(GC, xcc_id), regVML2_WALKER_MEM_ECC_STATUS, -				0x3); -	} -} - -static void gfx_v9_4_3_log_cu_timeout_status(struct amdgpu_device *adev, -					uint32_t status, int xcc_id) -{ -	struct amdgpu_cu_info *cu_info = &adev->gfx.cu_info; -	uint32_t i, simd, wave; -	uint32_t wave_status; -	uint32_t wave_pc_lo, wave_pc_hi; -	uint32_t wave_exec_lo, wave_exec_hi; -	uint32_t wave_inst_dw0, wave_inst_dw1; -	uint32_t wave_ib_sts; - -	for (i = 0; i < 32; i++) { -		if (!((i << 1) & status)) -			continue; - -		simd = i / cu_info->max_waves_per_simd; -		wave = i % cu_info->max_waves_per_simd; - -		wave_status = wave_read_ind(adev, xcc_id, simd, wave, ixSQ_WAVE_STATUS); -		wave_pc_lo = wave_read_ind(adev, xcc_id, simd, wave, ixSQ_WAVE_PC_LO); -		wave_pc_hi = wave_read_ind(adev, xcc_id, simd, wave, ixSQ_WAVE_PC_HI); -		wave_exec_lo = -			wave_read_ind(adev, xcc_id, simd, wave, ixSQ_WAVE_EXEC_LO); -		wave_exec_hi = -			wave_read_ind(adev, xcc_id, simd, wave, ixSQ_WAVE_EXEC_HI); -		wave_inst_dw0 = -			wave_read_ind(adev, xcc_id, simd, wave, ixSQ_WAVE_INST_DW0); -		wave_inst_dw1 = -			wave_read_ind(adev, xcc_id, simd, wave, ixSQ_WAVE_INST_DW1); -		wave_ib_sts = wave_read_ind(adev, xcc_id, simd, wave, ixSQ_WAVE_IB_STS); - -		dev_info( -			adev->dev, -			"\t SIMD %d, Wave %d: status 0x%x, pc 0x%llx, exec 0x%llx, inst 0x%llx, ib_sts 0x%x\n", -			simd, wave, wave_status, -			((uint64_t)wave_pc_hi << 32 | wave_pc_lo), -			((uint64_t)wave_exec_hi << 32 | wave_exec_lo), -			((uint64_t)wave_inst_dw1 << 32 | wave_inst_dw0), -			wave_ib_sts); -	} -} - -static void gfx_v9_4_3_inst_query_sq_timeout_status(struct amdgpu_device *adev, -					int xcc_id) -{ -	uint32_t se_idx, sh_idx, cu_idx; -	uint32_t status; - -	mutex_lock(&adev->grbm_idx_mutex); -	for (se_idx = 0; se_idx < adev->gfx.config.max_shader_engines; se_idx++) { -		for (sh_idx = 0; sh_idx < adev->gfx.config.max_sh_per_se; sh_idx++) { -			for (cu_idx = 0; cu_idx < adev->gfx.config.max_cu_per_sh; cu_idx++) { -				gfx_v9_4_3_xcc_select_se_sh(adev, se_idx, sh_idx, -							cu_idx, xcc_id); -				status = RREG32_SOC15(GC, GET_INST(GC, xcc_id), -						      regSQ_TIMEOUT_STATUS); -				if (status != 0) { -					dev_info( -						adev->dev, -						"GFX Watchdog Timeout: SE %d, SH %d, CU %d\n", -						se_idx, sh_idx, cu_idx); -					gfx_v9_4_3_log_cu_timeout_status( -						adev, status, xcc_id); -				} -				/* clear old status */ -				WREG32_SOC15(GC, GET_INST(GC, xcc_id), -						regSQ_TIMEOUT_STATUS, 0); -			} -		} -	} -	gfx_v9_4_3_xcc_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff, -			xcc_id); -	mutex_unlock(&adev->grbm_idx_mutex); -} - -static void gfx_v9_4_3_inst_query_ras_err_status(struct amdgpu_device *adev, -					void *ras_error_status, int xcc_id) -{ -	gfx_v9_4_3_inst_query_utc_err_status(adev, xcc_id); -	gfx_v9_4_3_inst_query_sq_timeout_status(adev, xcc_id); -} - -static void gfx_v9_4_3_inst_reset_utc_err_status(struct amdgpu_device *adev, -					int xcc_id) -{ -	WREG32_SOC15(GC, GET_INST(GC, xcc_id), regUTCL2_MEM_ECC_STATUS, 0x3); -	WREG32_SOC15(GC, GET_INST(GC, xcc_id), regVML2_MEM_ECC_STATUS, 0x3); -	WREG32_SOC15(GC, GET_INST(GC, xcc_id), regVML2_WALKER_MEM_ECC_STATUS, 0x3); -} - -static void gfx_v9_4_3_inst_reset_sq_timeout_status(struct amdgpu_device *adev, -					int xcc_id) -{ -	uint32_t se_idx, sh_idx, cu_idx; - -	mutex_lock(&adev->grbm_idx_mutex); -	for (se_idx = 0; se_idx < adev->gfx.config.max_shader_engines; se_idx++) { -		for (sh_idx = 0; sh_idx < adev->gfx.config.max_sh_per_se; sh_idx++) { -			for (cu_idx = 0; cu_idx < adev->gfx.config.max_cu_per_sh; cu_idx++) { -				gfx_v9_4_3_xcc_select_se_sh(adev, se_idx, sh_idx, -							cu_idx, xcc_id); -				WREG32_SOC15(GC, GET_INST(GC, xcc_id), -						regSQ_TIMEOUT_STATUS, 0); -			} -		} -	} -	gfx_v9_4_3_xcc_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff, -			xcc_id); -	mutex_unlock(&adev->grbm_idx_mutex); -} - -static void gfx_v9_4_3_inst_reset_ras_err_status(struct amdgpu_device *adev, -					void *ras_error_status, int xcc_id) -{ -	gfx_v9_4_3_inst_reset_utc_err_status(adev, xcc_id); -	gfx_v9_4_3_inst_reset_sq_timeout_status(adev, xcc_id); -} -  static void gfx_v9_4_3_inst_enable_watchdog_timer(struct amdgpu_device *adev,  					void *ras_error_status, int xcc_id)  { @@ -4067,16 +3923,6 @@ static void gfx_v9_4_3_reset_ras_error_count(struct amdgpu_device *adev)  	amdgpu_gfx_ras_error_func(adev, NULL, gfx_v9_4_3_inst_reset_ras_err_count);  } -static void gfx_v9_4_3_query_ras_error_status(struct amdgpu_device *adev) -{ -	amdgpu_gfx_ras_error_func(adev, NULL, gfx_v9_4_3_inst_query_ras_err_status); -} - -static void gfx_v9_4_3_reset_ras_error_status(struct amdgpu_device *adev) -{ -	amdgpu_gfx_ras_error_func(adev, NULL, gfx_v9_4_3_inst_reset_ras_err_status); -} -  static void gfx_v9_4_3_enable_watchdog_timer(struct amdgpu_device *adev)  {  	amdgpu_gfx_ras_error_func(adev, NULL, gfx_v9_4_3_inst_enable_watchdog_timer); @@ -4394,8 +4240,6 @@ struct amdgpu_xcp_ip_funcs gfx_v9_4_3_xcp_funcs = {  struct amdgpu_ras_block_hw_ops  gfx_v9_4_3_ras_ops = {  	.query_ras_error_count = &gfx_v9_4_3_query_ras_error_count,  	.reset_ras_error_count = &gfx_v9_4_3_reset_ras_error_count, -	.query_ras_error_status = &gfx_v9_4_3_query_ras_error_status, -	.reset_ras_error_status = &gfx_v9_4_3_reset_ras_error_status,  };  struct amdgpu_gfx_ras gfx_v9_4_3_ras = { diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c index 53a2ba5fcf4b..22175da0e16a 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c @@ -102,7 +102,9 @@ static void gfxhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev)  		WREG32_SOC15_RLC(GC, 0, mmMC_VM_SYSTEM_APERTURE_LOW_ADDR,  			min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18); -		if (adev->apu_flags & AMD_APU_IS_RAVEN2) +		if (adev->apu_flags & (AMD_APU_IS_RAVEN2 | +				       AMD_APU_IS_RENOIR | +				       AMD_APU_IS_GREEN_SARDINE))  		       /*  			* Raven2 has a HW issue that it is unable to use the  			* vram which is out of MC_VM_SYSTEM_APERTURE_HIGH_ADDR. diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c index 55423ff1bb49..49aecdcee006 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c +++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c @@ -139,7 +139,9 @@ gfxhub_v1_2_xcc_init_system_aperture_regs(struct amdgpu_device *adev,  			WREG32_SOC15_RLC(GC, GET_INST(GC, i), regMC_VM_SYSTEM_APERTURE_LOW_ADDR,  				min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18); -			if (adev->apu_flags & AMD_APU_IS_RAVEN2) +			if (adev->apu_flags & (AMD_APU_IS_RAVEN2 | +					       AMD_APU_IS_RENOIR | +					       AMD_APU_IS_GREEN_SARDINE))  			       /*  				* Raven2 has a HW issue that it is unable to use the  				* vram which is out of MC_VM_SYSTEM_APERTURE_HIGH_ADDR. @@ -454,10 +456,12 @@ static void gfxhub_v1_2_xcc_gart_disable(struct amdgpu_device *adev,  		WREG32_SOC15_RLC(GC, GET_INST(GC, j), regMC_VM_MX_L1_TLB_CNTL, tmp);  		/* Setup L2 cache */ -		tmp = RREG32_SOC15(GC, GET_INST(GC, j), regVM_L2_CNTL); -		tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_CACHE, 0); -		WREG32_SOC15(GC, GET_INST(GC, j), regVM_L2_CNTL, tmp); -		WREG32_SOC15(GC, GET_INST(GC, j), regVM_L2_CNTL3, 0); +		if (!amdgpu_sriov_vf(adev)) { +			tmp = RREG32_SOC15(GC, GET_INST(GC, j), regVM_L2_CNTL); +			tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_CACHE, 0); +			WREG32_SOC15(GC, GET_INST(GC, j), regVM_L2_CNTL, tmp); +			WREG32_SOC15(GC, GET_INST(GC, j), regVM_L2_CNTL3, 0); +		}  	}  } diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c index a5a05c16c10d..6c5185608854 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c @@ -1041,6 +1041,10 @@ static int gmc_v10_0_hw_fini(void *handle)  	amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0); +	if (adev->gmc.ecc_irq.funcs && +		amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC)) +		amdgpu_irq_put(adev, &adev->gmc.ecc_irq, 0); +  	return 0;  } diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c index 23d7b548d13f..c9c653cfc765 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c @@ -941,6 +941,11 @@ static int gmc_v11_0_hw_fini(void *handle)  	}  	amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0); + +	if (adev->gmc.ecc_irq.funcs && +		amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC)) +		amdgpu_irq_put(adev, &adev->gmc.ecc_irq, 0); +  	gmc_v11_0_gart_disable(adev);  	return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c index 42e103d7077d..59d9215e5556 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c @@ -915,8 +915,8 @@ static int gmc_v6_0_hw_init(void *handle)  	if (amdgpu_emu_mode == 1)  		return amdgpu_gmc_vram_checking(adev); -	else -		return r; + +	return 0;  }  static int gmc_v6_0_hw_fini(void *handle) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index efc16e580f1e..45a2f8e031a2 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c @@ -1099,8 +1099,8 @@ static int gmc_v7_0_hw_init(void *handle)  	if (amdgpu_emu_mode == 1)  		return amdgpu_gmc_vram_checking(adev); -	else -		return r; + +	return 0;  }  static int gmc_v7_0_hw_fini(void *handle) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index ff4ae73d27ec..4422b27a3cc2 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c @@ -1219,8 +1219,8 @@ static int gmc_v8_0_hw_init(void *handle)  	if (amdgpu_emu_mode == 1)  		return amdgpu_gmc_vram_checking(adev); -	else -		return r; + +	return 0;  }  static int gmc_v8_0_hw_fini(void *handle) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 2ac5820e9c92..40a00ea0009f 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -883,7 +883,7 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,  	 * GRBM interface.  	 */  	if ((vmhub == AMDGPU_GFXHUB(0)) && -	    (adev->ip_versions[GC_HWIP][0] < IP_VERSION(9, 4, 2))) +	    (amdgpu_ip_version(adev, GC_HWIP, 0) < IP_VERSION(9, 4, 2)))  		RREG32_NO_KIQ(req);  	for (j = 0; j < adev->usec_timeout; j++) { @@ -1950,7 +1950,8 @@ static void gmc_v9_4_3_init_vram_info(struct amdgpu_device *adev)  	static const u32 regBIF_BIOS_SCRATCH_4 = 0x50;  	u32 vram_info; -	if (!amdgpu_sriov_vf(adev)) { +	/* Only for dGPU, vendor informaton is reliable */ +	if (!amdgpu_sriov_vf(adev) && !(adev->flags & AMD_IS_APU)) {  		vram_info = RREG32(regBIF_BIOS_SCRATCH_4);  		adev->gmc.vram_vendor = vram_info & 0xF;  	} @@ -2340,8 +2341,8 @@ static int gmc_v9_0_hw_init(void *handle)  	if (amdgpu_emu_mode == 1)  		return amdgpu_gmc_vram_checking(adev); -	else -		return r; + +	return 0;  }  /** @@ -2380,6 +2381,10 @@ static int gmc_v9_0_hw_fini(void *handle)  	amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0); +	if (adev->gmc.ecc_irq.funcs && +		amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC)) +		amdgpu_irq_put(adev, &adev->gmc.ecc_irq, 0); +  	return 0;  } diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c index aecad530b10a..2c02ae69883d 100644 --- a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c @@ -215,6 +215,11 @@ static u32 iceland_ih_get_wptr(struct amdgpu_device *adev,  	tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);  	WREG32(mmIH_RB_CNTL, tmp); +	/* Unset the CLEAR_OVERFLOW bit immediately so new overflows +	 * can be detected. +	 */ +	tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); +	WREG32(mmIH_RB_CNTL, tmp);  out:  	return (wptr & ih->ptr_mask); diff --git a/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c b/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c index d9ed7332d805..ad4ad39f128f 100644 --- a/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c @@ -418,6 +418,12 @@ static u32 ih_v6_0_get_wptr(struct amdgpu_device *adev,  	tmp = RREG32_NO_KIQ(ih_regs->ih_rb_cntl);  	tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);  	WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); + +	/* Unset the CLEAR_OVERFLOW bit immediately so new overflows +	 * can be detected. +	 */ +	tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); +	WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp);  out:  	return (wptr & ih->ptr_mask);  } diff --git a/drivers/gpu/drm/amd/amdgpu/ih_v6_1.c b/drivers/gpu/drm/amd/amdgpu/ih_v6_1.c index 8fb05eae340a..b8da0fc29378 100644 --- a/drivers/gpu/drm/amd/amdgpu/ih_v6_1.c +++ b/drivers/gpu/drm/amd/amdgpu/ih_v6_1.c @@ -418,6 +418,13 @@ static u32 ih_v6_1_get_wptr(struct amdgpu_device *adev,  	tmp = RREG32_NO_KIQ(ih_regs->ih_rb_cntl);  	tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);  	WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); + +	/* Unset the CLEAR_OVERFLOW bit immediately so new overflows +	 * can be detected. +	 */ +	tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); +	WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); +  out:  	return (wptr & ih->ptr_mask);  } diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c index 4dfec56e1b7f..26d71a22395d 100644 --- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c @@ -408,6 +408,8 @@ static int mes_v11_0_set_hw_resources(struct amdgpu_mes *mes)  	mes_set_hw_res_pkt.enable_reg_active_poll = 1;  	mes_set_hw_res_pkt.enable_level_process_quantum_check = 1;  	mes_set_hw_res_pkt.oversubscription_timer = 50; +	mes_set_hw_res_pkt.enable_mes_event_int_logging = 1; +	mes_set_hw_res_pkt.event_intr_history_gpu_mc_ptr = mes->event_log_gpu_addr;  	return mes_v11_0_submit_pkt_and_poll_completion(mes,  			&mes_set_hw_res_pkt, sizeof(mes_set_hw_res_pkt), diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c index 843219a91736..e3ddd22aa172 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c @@ -96,7 +96,9 @@ static void mmhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev)  	WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_LOW_ADDR,  		     min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18); -	if (adev->apu_flags & AMD_APU_IS_RAVEN2) +	if (adev->apu_flags & (AMD_APU_IS_RAVEN2 | +			       AMD_APU_IS_RENOIR | +			       AMD_APU_IS_GREEN_SARDINE))  		/*  		 * Raven2 has a HW issue that it is unable to use the vram which  		 * is out of MC_VM_SYSTEM_APERTURE_HIGH_ADDR. So here is the diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c index 9b0146732e13..fb53aacdcba2 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c @@ -652,8 +652,8 @@ static void mmhub_v1_8_inst_query_ras_error_count(struct amdgpu_device *adev,  					AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE,  					&ue_count); -	amdgpu_ras_error_statistic_ce_count(err_data, &mcm_info, ce_count); -	amdgpu_ras_error_statistic_ue_count(err_data, &mcm_info, ue_count); +	amdgpu_ras_error_statistic_ce_count(err_data, &mcm_info, NULL, ce_count); +	amdgpu_ras_error_statistic_ue_count(err_data, &mcm_info, NULL, ue_count);  }  static void mmhub_v1_8_query_ras_error_count(struct amdgpu_device *adev, diff --git a/drivers/gpu/drm/amd/amdgpu/navi10_ih.c b/drivers/gpu/drm/amd/amdgpu/navi10_ih.c index e64b33115848..de93614726c9 100644 --- a/drivers/gpu/drm/amd/amdgpu/navi10_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/navi10_ih.c @@ -442,6 +442,12 @@ static u32 navi10_ih_get_wptr(struct amdgpu_device *adev,  	tmp = RREG32_NO_KIQ(ih_regs->ih_rb_cntl);  	tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);  	WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); + +	/* Unset the CLEAR_OVERFLOW bit immediately so new overflows +	 * can be detected. +	 */ +	tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); +	WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp);  out:  	return (wptr & ih->ptr_mask);  } diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c index 6d24c84924cb..19986ff6a48d 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c @@ -401,8 +401,7 @@ static void nbio_v7_4_handle_ras_controller_intr_no_bifring(struct amdgpu_device  			if (err_data.ce_count)  				dev_info(adev->dev, "%ld correctable hardware " -						"errors detected in %s block, " -						"no user action is needed.\n", +						"errors detected in %s block\n",  						obj->err_data.ce_count,  						get_ras_block_str(adev->nbio.ras_if)); diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c index 25a3da83e0fb..e90f33780803 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c @@ -597,8 +597,7 @@ static void nbio_v7_9_handle_ras_controller_intr_no_bifring(struct amdgpu_device  			if (err_data.ce_count)  				dev_info(adev->dev, "%ld correctable hardware " -						"errors detected in %s block, " -						"no user action is needed.\n", +						"errors detected in %s block\n",  						obj->err_data.ce_count,  						get_ras_block_str(adev->nbio.ras_if)); diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c index 0f24af6f2810..2d688dca26be 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c @@ -2156,7 +2156,7 @@ static void sdma_v4_4_2_inst_query_ras_error_count(struct amdgpu_device *adev,  					AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE,  					&ue_count); -	amdgpu_ras_error_statistic_ue_count(err_data, &mcm_info, ue_count); +	amdgpu_ras_error_statistic_ue_count(err_data, &mcm_info, NULL, ue_count);  }  static void sdma_v4_4_2_query_ras_error_count(struct amdgpu_device *adev, diff --git a/drivers/gpu/drm/amd/amdgpu/si_ih.c b/drivers/gpu/drm/amd/amdgpu/si_ih.c index 9a24f17a5750..cada9f300a7f 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/si_ih.c @@ -119,6 +119,12 @@ static u32 si_ih_get_wptr(struct amdgpu_device *adev,  		tmp = RREG32(IH_RB_CNTL);  		tmp |= IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK;  		WREG32(IH_RB_CNTL, tmp); + +		/* Unset the CLEAR_OVERFLOW bit immediately so new overflows +		 * can be detected. +		 */ +		tmp &= ~IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK; +		WREG32(IH_RB_CNTL, tmp);  	}  	return (wptr & ih->ptr_mask);  } diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index 51342809af03..15033efec2ba 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c @@ -902,6 +902,7 @@ static const struct amdgpu_asic_funcs aqua_vanjaram_asic_funcs =  	.pre_asic_init = &soc15_pre_asic_init,  	.query_video_codecs = &soc15_query_video_codecs,  	.encode_ext_smn_addressing = &aqua_vanjaram_encode_ext_smn_addressing, +	.get_reg_state = &aqua_vanjaram_get_reg_state,  };  static int soc15_common_early_init(void *handle) diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.h b/drivers/gpu/drm/amd/amdgpu/soc15.h index eac54042c6c0..1444b7765e4b 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.h +++ b/drivers/gpu/drm/amd/amdgpu/soc15.h @@ -27,6 +27,7 @@  #include "nbio_v6_1.h"  #include "nbio_v7_0.h"  #include "nbio_v7_4.h" +#include "amdgpu_reg_state.h"  extern const struct amdgpu_ip_block_version vega10_common_ip_block; @@ -114,6 +115,9 @@ int aldebaran_reg_base_init(struct amdgpu_device *adev);  void aqua_vanjaram_ip_map_init(struct amdgpu_device *adev);  u64 aqua_vanjaram_encode_ext_smn_addressing(int ext_id);  int aqua_vanjaram_init_soc_config(struct amdgpu_device *adev); +ssize_t aqua_vanjaram_get_reg_state(struct amdgpu_device *adev, +				    enum amdgpu_reg_state reg_state, void *buf, +				    size_t max_size);  void vega10_doorbell_index_init(struct amdgpu_device *adev);  void vega20_doorbell_index_init(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c index 917707bba7f3..450b6e831509 100644 --- a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c @@ -219,6 +219,12 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev,  	tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);  	WREG32(mmIH_RB_CNTL, tmp); +	/* Unset the CLEAR_OVERFLOW bit immediately so new overflows +	 * can be detected. +	 */ +	tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); +	WREG32(mmIH_RB_CNTL, tmp); +  out:  	return (wptr & ih->ptr_mask);  } diff --git a/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c b/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c index e9c2ff74f0bc..7458a218e89d 100644 --- a/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c +++ b/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c @@ -26,6 +26,7 @@  #include "amdgpu.h"  #include "umc/umc_12_0_0_offset.h"  #include "umc/umc_12_0_0_sh_mask.h" +#include "mp/mp_13_0_6_sh_mask.h"  const uint32_t  	umc_v12_0_channel_idx_tbl[] @@ -88,16 +89,26 @@ static void umc_v12_0_reset_error_count(struct amdgpu_device *adev)  		umc_v12_0_reset_error_count_per_channel, NULL);  } -bool umc_v12_0_is_uncorrectable_error(uint64_t mc_umc_status) +bool umc_v12_0_is_uncorrectable_error(struct amdgpu_device *adev, uint64_t mc_umc_status)  { +	if (amdgpu_ras_is_poison_mode_supported(adev) && +	    (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1) && +	    (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Deferred) == 1)) +		return true; +  	return ((REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1) &&  		(REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, PCC) == 1 ||  		REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UC) == 1 ||  		REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, TCC) == 1));  } -bool umc_v12_0_is_correctable_error(uint64_t mc_umc_status) +bool umc_v12_0_is_correctable_error(struct amdgpu_device *adev, uint64_t mc_umc_status)  { +	if (amdgpu_ras_is_poison_mode_supported(adev) && +	    (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1) && +	    (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Deferred) == 1)) +		return false; +  	return (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&  		(REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1 ||  		(REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 && @@ -105,7 +116,7 @@ bool umc_v12_0_is_correctable_error(uint64_t mc_umc_status)  		/* Identify data parity error in replay mode */  		((REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, ErrorCodeExt) == 0x5 ||  		REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, ErrorCodeExt) == 0xb) && -		!(umc_v12_0_is_uncorrectable_error(mc_umc_status))))); +		!(umc_v12_0_is_uncorrectable_error(adev, mc_umc_status)))));  }  static void umc_v12_0_query_correctable_error_count(struct amdgpu_device *adev, @@ -124,7 +135,7 @@ static void umc_v12_0_query_correctable_error_count(struct amdgpu_device *adev,  	mc_umc_status =  		RREG64_PCIE_EXT((mc_umc_status_addr + umc_reg_offset) * 4); -	if (umc_v12_0_is_correctable_error(mc_umc_status)) +	if (umc_v12_0_is_correctable_error(adev, mc_umc_status))  		*error_count += 1;  } @@ -142,7 +153,7 @@ static void umc_v12_0_query_uncorrectable_error_count(struct amdgpu_device *adev  	mc_umc_status =  		RREG64_PCIE_EXT((mc_umc_status_addr + umc_reg_offset) * 4); -	if (umc_v12_0_is_uncorrectable_error(mc_umc_status)) +	if (umc_v12_0_is_uncorrectable_error(adev, mc_umc_status))  		*error_count += 1;  } @@ -166,8 +177,8 @@ static int umc_v12_0_query_error_count(struct amdgpu_device *adev,  	umc_v12_0_query_correctable_error_count(adev, umc_reg_offset, &ce_count);  	umc_v12_0_query_uncorrectable_error_count(adev, umc_reg_offset, &ue_count); -	amdgpu_ras_error_statistic_ue_count(err_data, &mcm_info, ue_count); -	amdgpu_ras_error_statistic_ce_count(err_data, &mcm_info, ce_count); +	amdgpu_ras_error_statistic_ue_count(err_data, &mcm_info, NULL, ue_count); +	amdgpu_ras_error_statistic_ce_count(err_data, &mcm_info, NULL, ce_count);  	return 0;  } @@ -360,6 +371,59 @@ static int umc_v12_0_err_cnt_init_per_channel(struct amdgpu_device *adev,  	return 0;  } +static void umc_v12_0_ecc_info_query_ras_error_count(struct amdgpu_device *adev, +					void *ras_error_status) +{ +	amdgpu_mca_smu_log_ras_error(adev, +		AMDGPU_RAS_BLOCK__UMC, AMDGPU_MCA_ERROR_TYPE_CE, ras_error_status); +	amdgpu_mca_smu_log_ras_error(adev, +		AMDGPU_RAS_BLOCK__UMC, AMDGPU_MCA_ERROR_TYPE_UE, ras_error_status); +} + +static void umc_v12_0_ecc_info_query_ras_error_address(struct amdgpu_device *adev, +					void *ras_error_status) +{ +	struct ras_err_node *err_node; +	uint64_t mc_umc_status; +	struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status; + +	for_each_ras_error(err_node, err_data) { +		mc_umc_status = err_node->err_info.err_addr.err_status; +		if (!mc_umc_status) +			continue; + +		if (umc_v12_0_is_uncorrectable_error(adev, mc_umc_status)) { +			uint64_t mca_addr, err_addr, mca_ipid; +			uint32_t InstanceIdLo; +			struct amdgpu_smuio_mcm_config_info *mcm_info; + +			mcm_info = &err_node->err_info.mcm_info; +			mca_addr = err_node->err_info.err_addr.err_addr; +			mca_ipid = err_node->err_info.err_addr.err_ipid; + +			err_addr =  REG_GET_FIELD(mca_addr, MCA_UMC_UMC0_MCUMC_ADDRT0, ErrorAddr); +			InstanceIdLo = REG_GET_FIELD(mca_ipid, MCMP1_IPIDT0, InstanceIdLo); + +			dev_info(adev->dev, "UMC:IPID:0x%llx, aid:%d, inst:%d, ch:%d, err_addr:0x%llx\n", +				mca_ipid, +				mcm_info->die_id, +				MCA_IPID_LO_2_UMC_INST(InstanceIdLo), +				MCA_IPID_LO_2_UMC_CH(InstanceIdLo), +				err_addr); + +			umc_v12_0_convert_error_address(adev, +				err_data, err_addr, +				MCA_IPID_LO_2_UMC_CH(InstanceIdLo), +				MCA_IPID_LO_2_UMC_INST(InstanceIdLo), +				mcm_info->die_id); + +			/* Clear umc error address content */ +			memset(&err_node->err_info.err_addr, +				0, sizeof(err_node->err_info.err_addr)); +		} +	} +} +  static void umc_v12_0_err_cnt_init(struct amdgpu_device *adev)  {  	amdgpu_umc_loop_channels(adev, @@ -386,4 +450,6 @@ struct amdgpu_umc_ras umc_v12_0_ras = {  	},  	.err_cnt_init = umc_v12_0_err_cnt_init,  	.query_ras_poison_mode = umc_v12_0_query_ras_poison_mode, +	.ecc_info_query_ras_error_count = umc_v12_0_ecc_info_query_ras_error_count, +	.ecc_info_query_ras_error_address = umc_v12_0_ecc_info_query_ras_error_address,  }; diff --git a/drivers/gpu/drm/amd/amdgpu/umc_v12_0.h b/drivers/gpu/drm/amd/amdgpu/umc_v12_0.h index b34b1e358f8b..e8de3a92251a 100644 --- a/drivers/gpu/drm/amd/amdgpu/umc_v12_0.h +++ b/drivers/gpu/drm/amd/amdgpu/umc_v12_0.h @@ -117,8 +117,12 @@  		(pa) |= (UMC_V12_0_CHANNEL_HASH_CH6(channel_idx, pa) << UMC_V12_0_PA_CH6_BIT); \  	} while (0) -bool umc_v12_0_is_uncorrectable_error(uint64_t mc_umc_status); -bool umc_v12_0_is_correctable_error(uint64_t mc_umc_status); +#define MCA_IPID_LO_2_UMC_CH(_ipid_lo) (((((_ipid_lo) >> 20) & 0x1) * 4) + \ +			(((_ipid_lo) >> 12) & 0xF)) +#define MCA_IPID_LO_2_UMC_INST(_ipid_lo) (((_ipid_lo) >> 21) & 0x7) + +bool umc_v12_0_is_uncorrectable_error(struct amdgpu_device *adev, uint64_t mc_umc_status); +bool umc_v12_0_is_correctable_error(struct amdgpu_device *adev, uint64_t mc_umc_status);  extern const uint32_t  	umc_v12_0_channel_idx_tbl[] diff --git a/drivers/gpu/drm/amd/amdgpu/umc_v6_7.c b/drivers/gpu/drm/amd/amdgpu/umc_v6_7.c index 530549314ce4..a3ee3c4c650f 100644 --- a/drivers/gpu/drm/amd/amdgpu/umc_v6_7.c +++ b/drivers/gpu/drm/amd/amdgpu/umc_v6_7.c @@ -64,7 +64,7 @@ static void umc_v6_7_query_error_status_helper(struct amdgpu_device *adev,  	uint64_t reg_value;  	if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Deferred) == 1) -		dev_info(adev->dev, "Deferred error, no user action is needed.\n"); +		dev_info(adev->dev, "Deferred error\n");  	if (mc_umc_status)  		dev_info(adev->dev, "MCA STATUS 0x%llx, umc_reg_offset 0x%x\n", mc_umc_status, umc_reg_offset); diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c index 48bfcd0d558b..8ab01ae919d2 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c @@ -100,6 +100,31 @@ static int vcn_v4_0_early_init(void *handle)  	return amdgpu_vcn_early_init(adev);  } +static int vcn_v4_0_fw_shared_init(struct amdgpu_device *adev, int inst_idx) +{ +	volatile struct amdgpu_vcn4_fw_shared *fw_shared; + +	fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr; +	fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE); +	fw_shared->sq.is_enabled = 1; + +	fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_SMU_DPM_INTERFACE_FLAG); +	fw_shared->smu_dpm_interface.smu_interface_type = (adev->flags & AMD_IS_APU) ? +		AMDGPU_VCN_SMU_DPM_INTERFACE_APU : AMDGPU_VCN_SMU_DPM_INTERFACE_DGPU; + +	if (amdgpu_ip_version(adev, VCN_HWIP, 0) == +	    IP_VERSION(4, 0, 2)) { +		fw_shared->present_flag_0 |= AMDGPU_FW_SHARED_FLAG_0_DRM_KEY_INJECT; +		fw_shared->drm_key_wa.method = +			AMDGPU_DRM_KEY_INJECT_WORKAROUND_VCNFW_ASD_HANDSHAKING; +	} + +	if (amdgpu_vcnfw_log) +		amdgpu_vcn_fwlog_init(&adev->vcn.inst[inst_idx]); + +	return 0; +} +  /**   * vcn_v4_0_sw_init - sw init for VCN block   * @@ -124,8 +149,6 @@ static int vcn_v4_0_sw_init(void *handle)  		return r;  	for (i = 0; i < adev->vcn.num_vcn_inst; i++) { -		volatile struct amdgpu_vcn4_fw_shared *fw_shared; -  		if (adev->vcn.harvest_config & (1 << i))  			continue; @@ -161,23 +184,7 @@ static int vcn_v4_0_sw_init(void *handle)  		if (r)  			return r; -		fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; -		fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE); -		fw_shared->sq.is_enabled = 1; - -		fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_SMU_DPM_INTERFACE_FLAG); -		fw_shared->smu_dpm_interface.smu_interface_type = (adev->flags & AMD_IS_APU) ? -			AMDGPU_VCN_SMU_DPM_INTERFACE_APU : AMDGPU_VCN_SMU_DPM_INTERFACE_DGPU; - -		if (amdgpu_ip_version(adev, VCN_HWIP, 0) == -		    IP_VERSION(4, 0, 2)) { -			fw_shared->present_flag_0 |= AMDGPU_FW_SHARED_FLAG_0_DRM_KEY_INJECT; -			fw_shared->drm_key_wa.method = -				AMDGPU_DRM_KEY_INJECT_WORKAROUND_VCNFW_ASD_HANDSHAKING; -		} - -		if (amdgpu_vcnfw_log) -			amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]); +		vcn_v4_0_fw_shared_init(adev, i);  	}  	if (amdgpu_sriov_vf(adev)) { @@ -1273,6 +1280,9 @@ static int vcn_v4_0_start_sriov(struct amdgpu_device *adev)  		if (adev->vcn.harvest_config & (1 << i))  			continue; +		// Must re/init fw_shared at beginning +		vcn_v4_0_fw_shared_init(adev, i); +  		table_size = 0;  		MMSCH_V4_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCN, i, @@ -2008,22 +2018,6 @@ static int vcn_v4_0_set_powergating_state(void *handle, enum amd_powergating_sta  }  /** - * vcn_v4_0_set_interrupt_state - set VCN block interrupt state - * - * @adev: amdgpu_device pointer - * @source: interrupt sources - * @type: interrupt types - * @state: interrupt states - * - * Set VCN block interrupt state - */ -static int vcn_v4_0_set_interrupt_state(struct amdgpu_device *adev, struct amdgpu_irq_src *source, -      unsigned type, enum amdgpu_interrupt_state state) -{ -	return 0; -} - -/**   * vcn_v4_0_set_ras_interrupt_state - set VCN block RAS interrupt state   *   * @adev: amdgpu_device pointer @@ -2087,7 +2081,6 @@ static int vcn_v4_0_process_interrupt(struct amdgpu_device *adev, struct amdgpu_  }  static const struct amdgpu_irq_src_funcs vcn_v4_0_irq_funcs = { -	.set = vcn_v4_0_set_interrupt_state,  	.process = vcn_v4_0_process_interrupt,  }; diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c index 2eda30e78f61..49e4c3c09aca 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c @@ -269,8 +269,6 @@ static int vcn_v4_0_5_hw_fini(void *handle)  				vcn_v4_0_5_set_powergating_state(adev, AMD_PG_STATE_GATE);  			}  		} - -		amdgpu_irq_put(adev, &adev->vcn.inst[i].irq, 0);  	}  	return 0; @@ -1669,22 +1667,6 @@ static int vcn_v4_0_5_set_powergating_state(void *handle, enum amd_powergating_s  }  /** - * vcn_v4_0_5_set_interrupt_state - set VCN block interrupt state - * - * @adev: amdgpu_device pointer - * @source: interrupt sources - * @type: interrupt types - * @state: interrupt states - * - * Set VCN block interrupt state - */ -static int vcn_v4_0_5_set_interrupt_state(struct amdgpu_device *adev, struct amdgpu_irq_src *source, -		unsigned type, enum amdgpu_interrupt_state state) -{ -	return 0; -} - -/**   * vcn_v4_0_5_process_interrupt - process VCN block interrupt   *   * @adev: amdgpu_device pointer @@ -1726,7 +1708,6 @@ static int vcn_v4_0_5_process_interrupt(struct amdgpu_device *adev, struct amdgp  }  static const struct amdgpu_irq_src_funcs vcn_v4_0_5_irq_funcs = { -	.set = vcn_v4_0_5_set_interrupt_state,  	.process = vcn_v4_0_5_process_interrupt,  }; diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c index d364c6dd152c..bf68e18e3824 100644 --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c @@ -373,6 +373,12 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev,  	tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);  	WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); +	/* Unset the CLEAR_OVERFLOW bit immediately so new overflows +	 * can be detected. +	 */ +	tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); +	WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); +  out:  	return (wptr & ih->ptr_mask);  } diff --git a/drivers/gpu/drm/amd/amdgpu/vega20_ih.c b/drivers/gpu/drm/amd/amdgpu/vega20_ih.c index ddfc6941f9d5..db66e6cccaf2 100644 --- a/drivers/gpu/drm/amd/amdgpu/vega20_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/vega20_ih.c @@ -421,6 +421,12 @@ static u32 vega20_ih_get_wptr(struct amdgpu_device *adev,  	tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);  	WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); +	/* Unset the CLEAR_OVERFLOW bit immediately so new overflows +	 * can be detected. +	 */ +	tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); +	WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); +  out:  	return (wptr & ih->ptr_mask);  } diff --git a/drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c b/drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c index 174f13eff575..d20060a51e05 100644 --- a/drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c +++ b/drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c @@ -96,6 +96,10 @@ static int vpe_v6_1_load_microcode(struct amdgpu_vpe *vpe)  		adev->vpe.cmdbuf_cpu_addr[1] = f32_cntl;  		amdgpu_vpe_psp_update_sram(adev); + +		/* Config DPM */ +		amdgpu_vpe_configure_dpm(vpe); +  		return 0;  	} @@ -128,6 +132,8 @@ static int vpe_v6_1_load_microcode(struct amdgpu_vpe *vpe)  	}  	vpe_v6_1_halt(vpe, false); +	/* Config DPM */ +	amdgpu_vpe_configure_dpm(vpe);  	return 0;  } @@ -264,6 +270,15 @@ static int vpe_v6_1_set_regs(struct amdgpu_vpe *vpe)  	vpe->regs.queue0_rb_wptr_hi = regVPEC_QUEUE0_RB_WPTR_HI;  	vpe->regs.queue0_preempt = regVPEC_QUEUE0_PREEMPT; +	vpe->regs.dpm_enable = regVPEC_PUB_DUMMY2; +	vpe->regs.dpm_pratio = regVPEC_QUEUE6_DUMMY4; +	vpe->regs.dpm_request_interval = regVPEC_QUEUE5_DUMMY3; +	vpe->regs.dpm_decision_threshold = regVPEC_QUEUE5_DUMMY4; +	vpe->regs.dpm_busy_clamp_threshold = regVPEC_QUEUE7_DUMMY2; +	vpe->regs.dpm_idle_clamp_threshold = regVPEC_QUEUE7_DUMMY3; +	vpe->regs.dpm_request_lv = regVPEC_QUEUE7_DUMMY1; +	vpe->regs.context_indicator = regVPEC_QUEUE6_DUMMY3; +  	return 0;  } | 
