diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 207 |
1 files changed, 157 insertions, 50 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index d30dc0b718c7..583cf03950cd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -200,6 +200,44 @@ out: return r; } +static enum amd_ip_block_type + amdgpu_ip_get_block_type(struct amdgpu_device *adev, uint32_t ip) +{ + enum amd_ip_block_type type; + + switch (ip) { + case AMDGPU_HW_IP_GFX: + type = AMD_IP_BLOCK_TYPE_GFX; + break; + case AMDGPU_HW_IP_COMPUTE: + type = AMD_IP_BLOCK_TYPE_GFX; + break; + case AMDGPU_HW_IP_DMA: + type = AMD_IP_BLOCK_TYPE_SDMA; + break; + case AMDGPU_HW_IP_UVD: + case AMDGPU_HW_IP_UVD_ENC: + type = AMD_IP_BLOCK_TYPE_UVD; + break; + case AMDGPU_HW_IP_VCE: + type = AMD_IP_BLOCK_TYPE_VCE; + break; + case AMDGPU_HW_IP_VCN_DEC: + case AMDGPU_HW_IP_VCN_ENC: + type = AMD_IP_BLOCK_TYPE_VCN; + break; + case AMDGPU_HW_IP_VCN_JPEG: + type = (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_JPEG)) ? + AMD_IP_BLOCK_TYPE_JPEG : AMD_IP_BLOCK_TYPE_VCN; + break; + default: + type = AMD_IP_BLOCK_TYPE_NUM; + break; + } + + return type; +} + static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info, struct drm_amdgpu_query_fw *query_fw, struct amdgpu_device *adev) @@ -352,6 +390,10 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info, fw_info->ver = adev->gfx.imu_fw_version; fw_info->feature = 0; break; + case AMDGPU_INFO_FW_VPE: + fw_info->ver = adev->vpe.fw_version; + fw_info->feature = adev->vpe.feature_version; + break; default: return -EINVAL; } @@ -405,7 +447,7 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev, if (adev->uvd.inst[i].ring.sched.ready) ++num_rings; } - ib_start_alignment = 64; + ib_start_alignment = 256; ib_size_alignment = 64; break; case AMDGPU_HW_IP_VCE: @@ -413,8 +455,8 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev, for (i = 0; i < adev->vce.num_rings; i++) if (adev->vce.ring[i].sched.ready) ++num_rings; - ib_start_alignment = 4; - ib_size_alignment = 1; + ib_start_alignment = 256; + ib_size_alignment = 4; break; case AMDGPU_HW_IP_UVD_ENC: type = AMD_IP_BLOCK_TYPE_UVD; @@ -426,8 +468,8 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev, if (adev->uvd.inst[i].ring_enc[j].sched.ready) ++num_rings; } - ib_start_alignment = 64; - ib_size_alignment = 64; + ib_start_alignment = 256; + ib_size_alignment = 4; break; case AMDGPU_HW_IP_VCN_DEC: type = AMD_IP_BLOCK_TYPE_VCN; @@ -438,8 +480,8 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev, if (adev->vcn.inst[i].ring_dec.sched.ready) ++num_rings; } - ib_start_alignment = 16; - ib_size_alignment = 16; + ib_start_alignment = 256; + ib_size_alignment = 64; break; case AMDGPU_HW_IP_VCN_ENC: type = AMD_IP_BLOCK_TYPE_VCN; @@ -451,8 +493,8 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev, if (adev->vcn.inst[i].ring_enc[j].sched.ready) ++num_rings; } - ib_start_alignment = 64; - ib_size_alignment = 1; + ib_start_alignment = 256; + ib_size_alignment = 4; break; case AMDGPU_HW_IP_VCN_JPEG: type = (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_JPEG)) ? @@ -466,8 +508,15 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev, if (adev->jpeg.inst[i].ring_dec[j].sched.ready) ++num_rings; } - ib_start_alignment = 16; - ib_size_alignment = 16; + ib_start_alignment = 256; + ib_size_alignment = 64; + break; + case AMDGPU_HW_IP_VPE: + type = AMD_IP_BLOCK_TYPE_VPE; + if (adev->vpe.ring.sched.ready) + ++num_rings; + ib_start_alignment = 256; + ib_size_alignment = 4; break; default: return -EINVAL; @@ -490,18 +539,26 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev, if (adev->asic_type >= CHIP_VEGA10) { switch (type) { case AMD_IP_BLOCK_TYPE_GFX: - result->ip_discovery_version = adev->ip_versions[GC_HWIP][0]; + result->ip_discovery_version = + IP_VERSION_MAJ_MIN_REV(amdgpu_ip_version(adev, GC_HWIP, 0)); break; case AMD_IP_BLOCK_TYPE_SDMA: - result->ip_discovery_version = adev->ip_versions[SDMA0_HWIP][0]; + result->ip_discovery_version = + IP_VERSION_MAJ_MIN_REV(amdgpu_ip_version(adev, SDMA0_HWIP, 0)); break; case AMD_IP_BLOCK_TYPE_UVD: case AMD_IP_BLOCK_TYPE_VCN: case AMD_IP_BLOCK_TYPE_JPEG: - result->ip_discovery_version = adev->ip_versions[UVD_HWIP][0]; + result->ip_discovery_version = + IP_VERSION_MAJ_MIN_REV(amdgpu_ip_version(adev, UVD_HWIP, 0)); break; case AMD_IP_BLOCK_TYPE_VCE: - result->ip_discovery_version = adev->ip_versions[VCE_HWIP][0]; + result->ip_discovery_version = + IP_VERSION_MAJ_MIN_REV(amdgpu_ip_version(adev, VCE_HWIP, 0)); + break; + case AMD_IP_BLOCK_TYPE_VPE: + result->ip_discovery_version = + IP_VERSION_MAJ_MIN_REV(amdgpu_ip_version(adev, VPE_HWIP, 0)); break; default: result->ip_discovery_version = 0; @@ -538,11 +595,16 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) struct drm_amdgpu_info *info = data; struct amdgpu_mode_info *minfo = &adev->mode_info; void __user *out = (void __user *)(uintptr_t)info->return_pointer; + struct amdgpu_fpriv *fpriv; + struct amdgpu_ip_block *ip_block; + enum amd_ip_block_type type; + struct amdgpu_xcp *xcp; + u32 count, inst_mask; uint32_t size = info->return_size; struct drm_crtc *crtc; uint32_t ui32 = 0; uint64_t ui64 = 0; - int i, found; + int i, found, ret; int ui32_size = sizeof(ui32); if (!info->return_size || !info->return_pointer) @@ -570,7 +632,6 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) return copy_to_user(out, &ui32, min(size, 4u)) ? -EFAULT : 0; case AMDGPU_INFO_HW_IP_INFO: { struct drm_amdgpu_info_hw_ip ip = {}; - int ret; ret = amdgpu_hw_ip_info(adev, info, &ip); if (ret) @@ -580,46 +641,66 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) return ret ? -EFAULT : 0; } case AMDGPU_INFO_HW_IP_COUNT: { - enum amd_ip_block_type type; - uint32_t count = 0; + fpriv = (struct amdgpu_fpriv *)filp->driver_priv; + type = amdgpu_ip_get_block_type(adev, info->query_hw_ip.type); + ip_block = amdgpu_device_ip_get_ip_block(adev, type); - switch (info->query_hw_ip.type) { - case AMDGPU_HW_IP_GFX: - type = AMD_IP_BLOCK_TYPE_GFX; - break; - case AMDGPU_HW_IP_COMPUTE: - type = AMD_IP_BLOCK_TYPE_GFX; - break; - case AMDGPU_HW_IP_DMA: - type = AMD_IP_BLOCK_TYPE_SDMA; - break; - case AMDGPU_HW_IP_UVD: - type = AMD_IP_BLOCK_TYPE_UVD; + if (!ip_block || !ip_block->status.valid) + return -EINVAL; + + if (adev->xcp_mgr && adev->xcp_mgr->num_xcps > 0 && + fpriv->xcp_id >= 0 && fpriv->xcp_id < adev->xcp_mgr->num_xcps) { + xcp = &adev->xcp_mgr->xcp[fpriv->xcp_id]; + switch (type) { + case AMD_IP_BLOCK_TYPE_GFX: + ret = amdgpu_xcp_get_inst_details(xcp, AMDGPU_XCP_GFX, &inst_mask); + count = hweight32(inst_mask); + break; + case AMD_IP_BLOCK_TYPE_SDMA: + ret = amdgpu_xcp_get_inst_details(xcp, AMDGPU_XCP_SDMA, &inst_mask); + count = hweight32(inst_mask); + break; + case AMD_IP_BLOCK_TYPE_JPEG: + ret = amdgpu_xcp_get_inst_details(xcp, AMDGPU_XCP_VCN, &inst_mask); + count = hweight32(inst_mask) * adev->jpeg.num_jpeg_rings; + break; + case AMD_IP_BLOCK_TYPE_VCN: + ret = amdgpu_xcp_get_inst_details(xcp, AMDGPU_XCP_VCN, &inst_mask); + count = hweight32(inst_mask); + break; + default: + return -EINVAL; + } + if (ret) + return ret; + return copy_to_user(out, &count, min(size, 4u)) ? -EFAULT : 0; + } + + switch (type) { + case AMD_IP_BLOCK_TYPE_GFX: + case AMD_IP_BLOCK_TYPE_VCE: + count = 1; break; - case AMDGPU_HW_IP_VCE: - type = AMD_IP_BLOCK_TYPE_VCE; + case AMD_IP_BLOCK_TYPE_SDMA: + count = adev->sdma.num_instances; break; - case AMDGPU_HW_IP_UVD_ENC: - type = AMD_IP_BLOCK_TYPE_UVD; + case AMD_IP_BLOCK_TYPE_JPEG: + count = adev->jpeg.num_jpeg_inst * adev->jpeg.num_jpeg_rings; break; - case AMDGPU_HW_IP_VCN_DEC: - case AMDGPU_HW_IP_VCN_ENC: - type = AMD_IP_BLOCK_TYPE_VCN; + case AMD_IP_BLOCK_TYPE_VCN: + count = adev->vcn.num_vcn_inst; break; - case AMDGPU_HW_IP_VCN_JPEG: - type = (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_JPEG)) ? - AMD_IP_BLOCK_TYPE_JPEG : AMD_IP_BLOCK_TYPE_VCN; + case AMD_IP_BLOCK_TYPE_UVD: + count = adev->uvd.num_uvd_inst; break; + /* For all other IP block types not listed in the switch statement + * the ip status is valid here and the instance count is one. + */ default: - return -EINVAL; + count = 1; + break; } - for (i = 0; i < adev->num_ip_blocks; i++) - if (adev->ip_blocks[i].version->type == type && - adev->ip_blocks[i].status.valid && - count < AMDGPU_HW_IP_INSTANCE_MAX_COUNT) - count++; - return copy_to_user(out, &count, min(size, 4u)) ? -EFAULT : 0; } case AMDGPU_INFO_TIMESTAMP: @@ -627,7 +708,6 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0; case AMDGPU_INFO_FW_VERSION: { struct drm_amdgpu_info_firmware fw_info; - int ret; /* We only support one instance of each IP block right now. */ if (info->query_fw.ip_instance != 0) @@ -772,7 +852,6 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) struct drm_amdgpu_info_device *dev_info; uint64_t vm_size; uint32_t pcie_gen_mask; - int ret; dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL); if (!dev_info) @@ -1173,6 +1252,26 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) return copy_to_user(out, max_ibs, min((size_t)size, sizeof(max_ibs))) ? -EFAULT : 0; } + case AMDGPU_INFO_GPUVM_FAULT: { + struct amdgpu_fpriv *fpriv = filp->driver_priv; + struct amdgpu_vm *vm = &fpriv->vm; + struct drm_amdgpu_info_gpuvm_fault gpuvm_fault; + unsigned long flags; + + if (!vm) + return -EINVAL; + + memset(&gpuvm_fault, 0, sizeof(gpuvm_fault)); + + xa_lock_irqsave(&adev->vm_manager.pasids, flags); + gpuvm_fault.addr = vm->fault_info.addr; + gpuvm_fault.status = vm->fault_info.status; + gpuvm_fault.vmhub = vm->fault_info.vmhub; + xa_unlock_irqrestore(&adev->vm_manager.pasids, flags); + + return copy_to_user(out, &gpuvm_fault, + min((size_t)size, sizeof(gpuvm_fault))) ? -EFAULT : 0; + } default: DRM_DEBUG_KMS("Invalid request %d\n", info->query); return -EINVAL; @@ -1729,6 +1828,14 @@ static int amdgpu_debugfs_firmware_info_show(struct seq_file *m, void *unused) seq_printf(m, "MES feature version: %u, firmware version: 0x%08x\n", fw_info.feature, fw_info.ver); + /* VPE */ + query_fw.fw_type = AMDGPU_INFO_FW_VPE; + ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); + if (ret) + return ret; + seq_printf(m, "VPE feature version: %u, firmware version: 0x%08x\n", + fw_info.feature, fw_info.ver); + seq_printf(m, "VBIOS version: %s\n", ctx->vbios_pn); return 0; |