1*c02697cbSDavid Zhang // SPDX-License-Identifier: GPL-2.0 2*c02697cbSDavid Zhang /* 3*c02697cbSDavid Zhang * Copyright (C) 2026, Advanced Micro Devices, Inc. 4*c02697cbSDavid Zhang */ 5*c02697cbSDavid Zhang 6*c02697cbSDavid Zhang #include <drm/amdxdna_accel.h> 7*c02697cbSDavid Zhang #include <drm/drm_print.h> 8*c02697cbSDavid Zhang #include <linux/pci.h> 9*c02697cbSDavid Zhang 10*c02697cbSDavid Zhang #include "aie.h" 11*c02697cbSDavid Zhang #include "aie4_msg_priv.h" 12*c02697cbSDavid Zhang #include "aie4_pci.h" 13*c02697cbSDavid Zhang #include "amdxdna_mailbox.h" 14*c02697cbSDavid Zhang #include "amdxdna_mailbox_helper.h" 15*c02697cbSDavid Zhang #include "amdxdna_pci_drv.h" 16*c02697cbSDavid Zhang 17*c02697cbSDavid Zhang static int aie4_destroy_vfs(struct amdxdna_dev_hdl *ndev) 18*c02697cbSDavid Zhang { 19*c02697cbSDavid Zhang DECLARE_AIE_MSG(aie4_msg_destroy_vfs, AIE4_MSG_OP_DESTROY_VFS); 20*c02697cbSDavid Zhang int ret; 21*c02697cbSDavid Zhang 22*c02697cbSDavid Zhang ret = aie_send_mgmt_msg_wait(&ndev->aie, &msg); 23*c02697cbSDavid Zhang if (ret) 24*c02697cbSDavid Zhang XDNA_ERR(ndev->aie.xdna, "destroy vfs op failed: %d", ret); 25*c02697cbSDavid Zhang 26*c02697cbSDavid Zhang return ret; 27*c02697cbSDavid Zhang } 28*c02697cbSDavid Zhang 29*c02697cbSDavid Zhang static int aie4_create_vfs(struct amdxdna_dev_hdl *ndev, int num_vfs) 30*c02697cbSDavid Zhang { 31*c02697cbSDavid Zhang DECLARE_AIE_MSG(aie4_msg_create_vfs, AIE4_MSG_OP_CREATE_VFS); 32*c02697cbSDavid Zhang int ret; 33*c02697cbSDavid Zhang 34*c02697cbSDavid Zhang req.vf_cnt = num_vfs; 35*c02697cbSDavid Zhang ret = aie_send_mgmt_msg_wait(&ndev->aie, &msg); 36*c02697cbSDavid Zhang if (ret) 37*c02697cbSDavid Zhang XDNA_ERR(ndev->aie.xdna, "create vfs op failed: %d", ret); 38*c02697cbSDavid Zhang 39*c02697cbSDavid Zhang return ret; 40*c02697cbSDavid Zhang } 41*c02697cbSDavid Zhang 42*c02697cbSDavid Zhang int aie4_sriov_stop(struct amdxdna_dev_hdl *ndev) 43*c02697cbSDavid Zhang { 44*c02697cbSDavid Zhang struct amdxdna_dev *xdna = ndev->aie.xdna; 45*c02697cbSDavid Zhang struct pci_dev *pdev = to_pci_dev(xdna->ddev.dev); 46*c02697cbSDavid Zhang int ret; 47*c02697cbSDavid Zhang 48*c02697cbSDavid Zhang if (!pci_num_vf(pdev)) 49*c02697cbSDavid Zhang return 0; 50*c02697cbSDavid Zhang 51*c02697cbSDavid Zhang ret = pci_vfs_assigned(pdev); 52*c02697cbSDavid Zhang if (ret) { 53*c02697cbSDavid Zhang XDNA_ERR(xdna, "VFs are still assigned to VMs"); 54*c02697cbSDavid Zhang return -EPERM; 55*c02697cbSDavid Zhang } 56*c02697cbSDavid Zhang 57*c02697cbSDavid Zhang pci_disable_sriov(pdev); 58*c02697cbSDavid Zhang return aie4_destroy_vfs(ndev); 59*c02697cbSDavid Zhang } 60*c02697cbSDavid Zhang 61*c02697cbSDavid Zhang static int aie4_sriov_start(struct amdxdna_dev_hdl *ndev, int num_vfs) 62*c02697cbSDavid Zhang { 63*c02697cbSDavid Zhang struct amdxdna_dev *xdna = ndev->aie.xdna; 64*c02697cbSDavid Zhang struct pci_dev *pdev = to_pci_dev(xdna->ddev.dev); 65*c02697cbSDavid Zhang int ret; 66*c02697cbSDavid Zhang 67*c02697cbSDavid Zhang ret = aie4_create_vfs(ndev, num_vfs); 68*c02697cbSDavid Zhang if (ret) 69*c02697cbSDavid Zhang return ret; 70*c02697cbSDavid Zhang 71*c02697cbSDavid Zhang ret = pci_enable_sriov(pdev, num_vfs); 72*c02697cbSDavid Zhang if (ret) { 73*c02697cbSDavid Zhang XDNA_ERR(xdna, "configure VFs failed, ret: %d", ret); 74*c02697cbSDavid Zhang aie4_destroy_vfs(ndev); 75*c02697cbSDavid Zhang return ret; 76*c02697cbSDavid Zhang } 77*c02697cbSDavid Zhang 78*c02697cbSDavid Zhang return num_vfs; 79*c02697cbSDavid Zhang } 80*c02697cbSDavid Zhang 81*c02697cbSDavid Zhang int aie4_sriov_configure(struct amdxdna_dev *xdna, int num_vfs) 82*c02697cbSDavid Zhang { 83*c02697cbSDavid Zhang struct amdxdna_dev_hdl *ndev = xdna->dev_handle; 84*c02697cbSDavid Zhang 85*c02697cbSDavid Zhang drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock)); 86*c02697cbSDavid Zhang 87*c02697cbSDavid Zhang return (num_vfs) ? aie4_sriov_start(ndev, num_vfs) : aie4_sriov_stop(ndev); 88*c02697cbSDavid Zhang } 89