]> Git Repo - linux.git/blobdiff - drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
Merge tag 'kvm-x86-hyperv-6.8' of https://github.com/kvm-x86/linux into HEAD
[linux.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_kms.c
index d30dc0b718c73ee8c703592b56d41c62f87d9c19..583cf03950cd7fe981e1db8bab1f029dc5b39df8 100644 (file)
@@ -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;
This page took 0.045914 seconds and 4 git commands to generate.