diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 56 | 
1 files changed, 55 insertions, 1 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c index 55784a9f26c4..be4629cdac04 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c @@ -52,7 +52,7 @@ int amdgpu_gmc_pdb0_alloc(struct amdgpu_device *adev)  	struct amdgpu_bo_param bp;  	u64 vram_size = adev->gmc.xgmi.node_segment_size * adev->gmc.xgmi.num_physical_nodes;  	uint32_t pde0_page_shift = adev->gmc.vmid0_page_table_block_size + 21; -	uint32_t npdes = (vram_size + (1ULL << pde0_page_shift) -1) >> pde0_page_shift; +	uint32_t npdes = (vram_size + (1ULL << pde0_page_shift) - 1) >> pde0_page_shift;  	memset(&bp, 0, sizeof(bp));  	bp.size = PAGE_ALIGN((npdes + 1) * 8); @@ -746,6 +746,59 @@ error_unlock_reset:  	return r;  } +void amdgpu_gmc_fw_reg_write_reg_wait(struct amdgpu_device *adev, +				      uint32_t reg0, uint32_t reg1, +				      uint32_t ref, uint32_t mask, +				      uint32_t xcc_inst) +{ +	struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_inst]; +	struct amdgpu_ring *ring = &kiq->ring; +	signed long r, cnt = 0; +	unsigned long flags; +	uint32_t seq; + +	if (adev->mes.ring.sched.ready) { +		amdgpu_mes_reg_write_reg_wait(adev, reg0, reg1, +					      ref, mask); +		return; +	} + +	spin_lock_irqsave(&kiq->ring_lock, flags); +	amdgpu_ring_alloc(ring, 32); +	amdgpu_ring_emit_reg_write_reg_wait(ring, reg0, reg1, +					    ref, mask); +	r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT); +	if (r) +		goto failed_undo; + +	amdgpu_ring_commit(ring); +	spin_unlock_irqrestore(&kiq->ring_lock, flags); + +	r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); + +	/* don't wait anymore for IRQ context */ +	if (r < 1 && in_interrupt()) +		goto failed_kiq; + +	might_sleep(); +	while (r < 1 && cnt++ < MAX_KIQ_REG_TRY) { + +		msleep(MAX_KIQ_REG_BAILOUT_INTERVAL); +		r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); +	} + +	if (cnt > MAX_KIQ_REG_TRY) +		goto failed_kiq; + +	return; + +failed_undo: +	amdgpu_ring_undo(ring); +	spin_unlock_irqrestore(&kiq->ring_lock, flags); +failed_kiq: +	dev_err(adev->dev, "failed to write reg %x wait reg %x\n", reg0, reg1); +} +  /**   * amdgpu_gmc_tmz_set -- check and set if a device supports TMZ   * @adev: amdgpu_device pointer @@ -790,6 +843,7 @@ void amdgpu_gmc_tmz_set(struct amdgpu_device *adev)  	case IP_VERSION(10, 3, 3):  	case IP_VERSION(11, 0, 4):  	case IP_VERSION(11, 5, 0): +	case IP_VERSION(11, 5, 1):  		/* Don't enable it by default yet.  		 */  		if (amdgpu_tmz < 1) { | 
