mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
accel/qaic: Add support for AI200 virtual functions
Register the qaic_pci_sriov_configure() callback to allow VFs to be created through AIC200's sysfs numvfs entry. Additionally, define a new MHI family for the 5 channels supported by AIC200 VFs: NNC, Telemetry, IPCR, Loopback and SSR. Co-developed-by: Troy Hanson <thanson@qti.qualcomm.com> Signed-off-by: Troy Hanson <thanson@qti.qualcomm.com> Signed-off-by: Zack McKevitt <zmckevit@qti.qualcomm.com> Signed-off-by: Youssef Samir <youssef.abdulrahman@oss.qualcomm.com> Reviewed-by: Jeff Hugo <jeff.hugo@oss.qualcomm.com> [jhugo: drop Sashiko tags from code review] Signed-off-by: Jeff Hugo <jeff.hugo@oss.qualcomm.com> Link: https://patch.msgid.link/20260831135008.1418190-1-youssef.abdulrahman@oss.qualcomm.com
This commit is contained in:
parent
018e5a0219
commit
c274d6aaa3
|
|
@ -23,6 +23,7 @@ MODULE_PARM_DESC(mhi_timeout_ms, "MHI controller timeout value");
|
|||
static const char *fw_image_paths[FAMILY_MAX] = {
|
||||
[FAMILY_AIC100] = "qcom/aic100/sbl.bin",
|
||||
[FAMILY_AIC200] = "qcom/aic200/sbl.bin",
|
||||
[FAMILY_AIC200_VF] = NULL,
|
||||
};
|
||||
|
||||
static const struct mhi_channel_config aic100_channels[] = {
|
||||
|
|
@ -691,6 +692,159 @@ static const struct mhi_channel_config aic200_channels[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static const struct mhi_channel_config aic200vf_channels[] = {
|
||||
{
|
||||
.name = "QAIC_LOOPBACK",
|
||||
.num = 0,
|
||||
.num_elements = 32,
|
||||
.local_elements = 0,
|
||||
.event_ring = 0,
|
||||
.dir = DMA_TO_DEVICE,
|
||||
.ee_mask = MHI_CH_EE_AMSS,
|
||||
.pollcfg = 0,
|
||||
.doorbell = MHI_DB_BRST_DISABLE,
|
||||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
.name = "QAIC_LOOPBACK",
|
||||
.num = 1,
|
||||
.num_elements = 32,
|
||||
.local_elements = 0,
|
||||
.event_ring = 0,
|
||||
.dir = DMA_FROM_DEVICE,
|
||||
.ee_mask = MHI_CH_EE_AMSS,
|
||||
.pollcfg = 0,
|
||||
.doorbell = MHI_DB_BRST_DISABLE,
|
||||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
.name = "QAIC_SSR",
|
||||
.num = 6,
|
||||
.num_elements = 32,
|
||||
.local_elements = 0,
|
||||
.event_ring = 0,
|
||||
.dir = DMA_TO_DEVICE,
|
||||
.ee_mask = MHI_CH_EE_AMSS,
|
||||
.pollcfg = 0,
|
||||
.doorbell = MHI_DB_BRST_DISABLE,
|
||||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
.name = "QAIC_SSR",
|
||||
.num = 7,
|
||||
.num_elements = 32,
|
||||
.local_elements = 0,
|
||||
.event_ring = 0,
|
||||
.dir = DMA_FROM_DEVICE,
|
||||
.ee_mask = MHI_CH_EE_AMSS,
|
||||
.pollcfg = 0,
|
||||
.doorbell = MHI_DB_BRST_DISABLE,
|
||||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
.name = "QAIC_CONTROL",
|
||||
.num = 10,
|
||||
.num_elements = 128,
|
||||
.local_elements = 0,
|
||||
.event_ring = 0,
|
||||
.dir = DMA_TO_DEVICE,
|
||||
.ee_mask = MHI_CH_EE_AMSS,
|
||||
.pollcfg = 0,
|
||||
.doorbell = MHI_DB_BRST_DISABLE,
|
||||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
.name = "QAIC_CONTROL",
|
||||
.num = 11,
|
||||
.num_elements = 128,
|
||||
.local_elements = 0,
|
||||
.event_ring = 0,
|
||||
.dir = DMA_FROM_DEVICE,
|
||||
.ee_mask = MHI_CH_EE_AMSS,
|
||||
.pollcfg = 0,
|
||||
.doorbell = MHI_DB_BRST_DISABLE,
|
||||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
.name = "QAIC_TELEMETRY",
|
||||
.num = 16,
|
||||
.num_elements = 32,
|
||||
.local_elements = 0,
|
||||
.event_ring = 0,
|
||||
.dir = DMA_TO_DEVICE,
|
||||
.ee_mask = MHI_CH_EE_AMSS,
|
||||
.pollcfg = 0,
|
||||
.doorbell = MHI_DB_BRST_DISABLE,
|
||||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
.name = "QAIC_TELEMETRY",
|
||||
.num = 17,
|
||||
.num_elements = 32,
|
||||
.local_elements = 0,
|
||||
.event_ring = 0,
|
||||
.dir = DMA_FROM_DEVICE,
|
||||
.ee_mask = MHI_CH_EE_AMSS,
|
||||
.pollcfg = 0,
|
||||
.doorbell = MHI_DB_BRST_DISABLE,
|
||||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
.name = "IPCR",
|
||||
.num = 24,
|
||||
.num_elements = 32,
|
||||
.local_elements = 0,
|
||||
.event_ring = 0,
|
||||
.dir = DMA_TO_DEVICE,
|
||||
.ee_mask = MHI_CH_EE_AMSS,
|
||||
.pollcfg = 0,
|
||||
.doorbell = MHI_DB_BRST_DISABLE,
|
||||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
{
|
||||
.name = "IPCR",
|
||||
.num = 25,
|
||||
.num_elements = 32,
|
||||
.local_elements = 0,
|
||||
.event_ring = 0,
|
||||
.dir = DMA_FROM_DEVICE,
|
||||
.ee_mask = MHI_CH_EE_AMSS,
|
||||
.pollcfg = 0,
|
||||
.doorbell = MHI_DB_BRST_DISABLE,
|
||||
.lpm_notify = false,
|
||||
.offload_channel = false,
|
||||
.doorbell_mode_switch = false,
|
||||
.wake_capable = false,
|
||||
},
|
||||
};
|
||||
|
||||
static struct mhi_event_config aic100_events[] = {
|
||||
{
|
||||
.num_elements = 32,
|
||||
|
|
@ -721,6 +875,21 @@ static struct mhi_event_config aic200_events[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct mhi_event_config aic200vf_events[] = {
|
||||
{
|
||||
.num_elements = 32,
|
||||
.irq_moderation_ms = 0,
|
||||
.irq = 0,
|
||||
.channel = U32_MAX,
|
||||
.priority = 1,
|
||||
.mode = MHI_DB_BRST_DISABLE,
|
||||
.data_type = MHI_ER_CTRL,
|
||||
.hardware_event = false,
|
||||
.client_managed = false,
|
||||
.offload_channel = false,
|
||||
},
|
||||
};
|
||||
|
||||
static struct mhi_controller_config mhi_cntrl_configs[] = {
|
||||
[FAMILY_AIC100] = {
|
||||
.max_channels = 128,
|
||||
|
|
@ -744,6 +913,17 @@ static struct mhi_controller_config mhi_cntrl_configs[] = {
|
|||
.use_bounce_buf = false,
|
||||
.m2_no_db = false,
|
||||
},
|
||||
[FAMILY_AIC200_VF] = {
|
||||
.max_channels = 128,
|
||||
.timeout_ms = 0, /* controlled by mhi_timeout */
|
||||
.buf_len = 0,
|
||||
.num_channels = ARRAY_SIZE(aic200vf_channels),
|
||||
.ch_cfg = aic200vf_channels,
|
||||
.num_events = ARRAY_SIZE(aic200vf_events),
|
||||
.event_cfg = aic200vf_events,
|
||||
.use_bounce_buf = false,
|
||||
.m2_no_db = false,
|
||||
},
|
||||
};
|
||||
|
||||
static int mhi_read_reg(struct mhi_controller *mhi_cntrl, void __iomem *addr, u32 *out)
|
||||
|
|
@ -864,11 +1044,19 @@ struct mhi_controller *qaic_mhi_register_controller(struct pci_dev *pci_dev, voi
|
|||
|
||||
mhi_cntrl->fw_image = fw_image_paths[family];
|
||||
|
||||
if (family == FAMILY_AIC200) {
|
||||
switch (family) {
|
||||
case FAMILY_AIC200:
|
||||
mhi_cntrl->name = "AIC200";
|
||||
mhi_cntrl->seg_len = SZ_512K;
|
||||
} else {
|
||||
break;
|
||||
case FAMILY_AIC200_VF:
|
||||
mhi_cntrl->name = "AIC200_VF";
|
||||
break;
|
||||
case FAMILY_AIC100:
|
||||
mhi_cntrl->name = "AIC100";
|
||||
break;
|
||||
default:
|
||||
mhi_cntrl->name = NULL;
|
||||
}
|
||||
|
||||
/* use latest configured timeout */
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
enum aic_families {
|
||||
FAMILY_AIC100,
|
||||
FAMILY_AIC200,
|
||||
FAMILY_AIC200_VF,
|
||||
FAMILY_MAX,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ MODULE_IMPORT_NS("DMA_BUF");
|
|||
#define PCI_DEVICE_ID_QCOM_AIC080 0xa080
|
||||
#define PCI_DEVICE_ID_QCOM_AIC100 0xa100
|
||||
#define PCI_DEVICE_ID_QCOM_AIC200 0xa110
|
||||
#define PCI_DEVICE_ID_QCOM_AIC200VF 0xa111
|
||||
#define QAIC_NAME "qaic"
|
||||
#define QAIC_DESC "Qualcomm Cloud AI Accelerators"
|
||||
#define CNTL_MAJOR 5
|
||||
|
|
@ -78,6 +79,13 @@ static const struct qaic_device_config aic200_config = {
|
|||
.dbc_bar_idx = 2,
|
||||
};
|
||||
|
||||
static const struct qaic_device_config aic200vf_config = {
|
||||
.family = FAMILY_AIC200_VF,
|
||||
.bar_mask = BIT(0) | BIT(1) | BIT(2) | BIT(4),
|
||||
.mhi_bar_idx = 1,
|
||||
.dbc_bar_idx = 2,
|
||||
};
|
||||
|
||||
bool datapath_polling;
|
||||
module_param(datapath_polling, bool, 0400);
|
||||
MODULE_PARM_DESC(datapath_polling, "Operate the datapath in polling mode");
|
||||
|
|
@ -610,6 +618,8 @@ static void qaic_pci_remove(struct pci_dev *pdev)
|
|||
{
|
||||
struct qaic_device *qdev = pci_get_drvdata(pdev);
|
||||
|
||||
pci_disable_sriov(pdev);
|
||||
|
||||
if (!qdev)
|
||||
return;
|
||||
|
||||
|
|
@ -666,6 +676,7 @@ static const struct pci_device_id qaic_ids[] = {
|
|||
{ PCI_DEVICE_DATA(QCOM, AIC080, (kernel_ulong_t)&aic080_config), },
|
||||
{ PCI_DEVICE_DATA(QCOM, AIC100, (kernel_ulong_t)&aic100_config), },
|
||||
{ PCI_DEVICE_DATA(QCOM, AIC200, (kernel_ulong_t)&aic200_config), },
|
||||
{ PCI_DEVICE_DATA(QCOM, AIC200VF, (kernel_ulong_t)&aic200vf_config), },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, qaic_ids);
|
||||
|
|
@ -762,6 +773,41 @@ static const struct dev_pm_ops qaic_pm_ops = {
|
|||
SYSTEM_SLEEP_PM_OPS(qaic_pm_suspend, qaic_pm_resume)
|
||||
};
|
||||
|
||||
static int qaic_pci_sriov_configure(struct pci_dev *pdev, int num_vfs)
|
||||
{
|
||||
struct qaic_device *qdev = pci_get_drvdata(pdev);
|
||||
int rcu_id;
|
||||
int ret;
|
||||
|
||||
if (num_vfs == 0) {
|
||||
pci_disable_sriov(pdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rcu_id = srcu_read_lock(&qdev->dev_lock);
|
||||
/* Qaic device must be online to process VF bringup */
|
||||
if (qdev->dev_state == QAIC_OFFLINE) {
|
||||
ret = -ENODEV;
|
||||
goto unlock_dev_srcu;
|
||||
}
|
||||
if (qdev->dev_state == QAIC_BOOT) {
|
||||
ret = -EBUSY;
|
||||
goto unlock_dev_srcu;
|
||||
}
|
||||
|
||||
ret = pci_enable_sriov(pdev, num_vfs);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to enable SR-IOV: %d (requested %d VFs, max %d)\n",
|
||||
ret, num_vfs, pci_sriov_get_totalvfs(pdev));
|
||||
goto unlock_dev_srcu;
|
||||
}
|
||||
|
||||
dev_dbg(&pdev->dev, "Successfully enabled %d VFs\n", num_vfs);
|
||||
unlock_dev_srcu:
|
||||
srcu_read_unlock(&qdev->dev_lock, rcu_id);
|
||||
return ret ?: num_vfs;
|
||||
}
|
||||
|
||||
static struct pci_driver qaic_pci_driver = {
|
||||
.name = QAIC_NAME,
|
||||
.id_table = qaic_ids,
|
||||
|
|
@ -769,6 +815,7 @@ static struct pci_driver qaic_pci_driver = {
|
|||
.remove = qaic_pci_remove,
|
||||
.shutdown = qaic_pci_shutdown,
|
||||
.err_handler = &qaic_pci_err_handler,
|
||||
.sriov_configure = qaic_pci_sriov_configure,
|
||||
.driver = {
|
||||
.pm = pm_sleep_ptr(&qaic_pm_ops),
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user