Merge tag 'kbuild-fixes-v6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/masahi...
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_kms.c
index 12414a7..583cf03 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)
@@ -557,6 +619,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
                        crtc = (struct drm_crtc *)minfo->crtcs[i];
                        if (crtc && crtc->base.id == info->mode_crtc.id) {
                                struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
+
                                ui32 = amdgpu_crtc->crtc_id;
                                found = 1;
                                break;
@@ -569,56 +632,75 @@ 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)
                        return ret;
 
-               ret = copy_to_user(out, &ip, min((size_t)size, sizeof(ip)));
+               ret = copy_to_user(out, &ip, min_t(size_t, size, sizeof(ip)));
                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:
@@ -626,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)
@@ -721,17 +802,18 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
                                    ? -EFAULT : 0;
        }
        case AMDGPU_INFO_READ_MMR_REG: {
-               unsigned n, alloc_size;
+               unsigned int n, alloc_size;
                uint32_t *regs;
-               unsigned se_num = (info->read_mmr_reg.instance >>
+               unsigned int se_num = (info->read_mmr_reg.instance >>
                                   AMDGPU_INFO_MMR_SE_INDEX_SHIFT) &
                                  AMDGPU_INFO_MMR_SE_INDEX_MASK;
-               unsigned sh_num = (info->read_mmr_reg.instance >>
+               unsigned int sh_num = (info->read_mmr_reg.instance >>
                                   AMDGPU_INFO_MMR_SH_INDEX_SHIFT) &
                                  AMDGPU_INFO_MMR_SH_INDEX_MASK;
 
                /* set full masks if the userspace set all bits
-                * in the bitfields */
+                * in the bitfields
+                */
                if (se_num == AMDGPU_INFO_MMR_SE_INDEX_MASK)
                        se_num = 0xffffffff;
                else if (se_num >= AMDGPU_GFX_MAX_SE)
@@ -770,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)
@@ -837,7 +918,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
                memcpy(&dev_info->cu_ao_bitmap[0], &adev->gfx.cu_info.ao_cu_bitmap[0],
                       sizeof(adev->gfx.cu_info.ao_cu_bitmap));
                memcpy(&dev_info->cu_bitmap[0], &adev->gfx.cu_info.bitmap[0],
-                      sizeof(adev->gfx.cu_info.bitmap));
+                      sizeof(dev_info->cu_bitmap));
                dev_info->vram_type = adev->gmc.vram_type;
                dev_info->vram_bit_width = adev->gmc.vram_width;
                dev_info->vce_harvest_config = adev->vce.harvest_config;
@@ -896,7 +977,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
                return ret;
        }
        case AMDGPU_INFO_VCE_CLOCK_TABLE: {
-               unsigned i;
+               unsigned int i;
                struct drm_amdgpu_info_vce_clock_table vce_clk_table = {};
                struct amd_vce_state *vce_state;
 
@@ -938,12 +1019,17 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
                        struct atom_context *atom_context;
 
                        atom_context = adev->mode_info.atom_context;
-                       memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
-                       memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
-                       vbios_info.version = atom_context->version;
-                       memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
-                                               sizeof(atom_context->vbios_ver_str));
-                       memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
+                       if (atom_context) {
+                               memcpy(vbios_info.name, atom_context->name,
+                                      sizeof(atom_context->name));
+                               memcpy(vbios_info.vbios_pn, atom_context->vbios_pn,
+                                      sizeof(atom_context->vbios_pn));
+                               vbios_info.version = atom_context->version;
+                               memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
+                                      sizeof(atom_context->vbios_ver_str));
+                               memcpy(vbios_info.date, atom_context->date,
+                                      sizeof(atom_context->date));
+                       }
 
                        return copy_to_user(out, &vbios_info,
                                                min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
@@ -1017,7 +1103,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
                case AMDGPU_INFO_SENSOR_GPU_AVG_POWER:
                        /* get average GPU power */
                        if (amdgpu_dpm_read_sensor(adev,
-                                                  AMDGPU_PP_SENSOR_GPU_POWER,
+                                                  AMDGPU_PP_SENSOR_GPU_AVG_POWER,
                                                   (void *)&ui32, &ui32_size)) {
                                return -EINVAL;
                        }
@@ -1102,6 +1188,9 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
                struct drm_amdgpu_info_video_caps *caps;
                int r;
 
+               if (!adev->asic_funcs->query_video_codecs)
+                       return -EINVAL;
+
                switch (info->video_cap.type) {
                case AMDGPU_INFO_VIDEO_CAPS_DECODE:
                        r = amdgpu_asic_query_video_codecs(adev, false, &codecs);
@@ -1163,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;
@@ -1719,7 +1828,15 @@ 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);
 
-       seq_printf(m, "VBIOS version: %s\n", ctx->vbios_version);
+       /* 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;
 }