On Fri, Jan 17, 2025 at 10:09:43AM -0700, Jeffrey Hugo wrote:
> Add basic support for the new AIC200 product. The PCIe Device ID is
> 0xa110. With this, we can turn on the lights for AIC200 by leveraging
> much of the existing driver.
> 
> Co-developed-by: Youssef Samir <quic_yabdu...@quicinc.com>
> Signed-off-by: Youssef Samir <quic_yabdu...@quicinc.com>
> Signed-off-by: Jeffrey Hugo <quic_jh...@quicinc.com>

Acked-by: Manivannan Sadhasivam <manivannan.sadhasi...@linaro.org>

One suggestion for future cleanup: Consider using the macro definitions for
channel and event config.

- Mani

> Reviewed-by: Lizhi Hou <lizhi....@amd.com>
> ---
>  drivers/accel/qaic/mhi_controller.c | 360 ++++++++++++++++++++++++++--
>  drivers/accel/qaic/mhi_controller.h |   2 +-
>  drivers/accel/qaic/qaic.h           |   1 +
>  drivers/accel/qaic/qaic_drv.c       |  11 +-
>  drivers/accel/qaic/sahara.c         |  39 ++-
>  5 files changed, 395 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/accel/qaic/mhi_controller.c 
> b/drivers/accel/qaic/mhi_controller.c
> index 8ab82e78dd94..13a14c6c6168 100644
> --- a/drivers/accel/qaic/mhi_controller.c
> +++ b/drivers/accel/qaic/mhi_controller.c
> @@ -20,6 +20,11 @@ static unsigned int mhi_timeout_ms = 2000; /* 2 sec 
> default */
>  module_param(mhi_timeout_ms, uint, 0600);
>  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",
> +};
> +
>  static const struct mhi_channel_config aic100_channels[] = {
>       {
>               .name = "QAIC_LOOPBACK",
> @@ -439,6 +444,297 @@ static const struct mhi_channel_config 
> aic100_channels[] = {
>       },
>  };
>  
> +static const struct mhi_channel_config aic200_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,
> +             .auto_queue = 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,
> +             .auto_queue = false,
> +             .wake_capable = false,
> +     },
> +     {
> +             .name = "QAIC_SAHARA",
> +             .num = 2,
> +             .num_elements = 32,
> +             .local_elements = 0,
> +             .event_ring = 0,
> +             .dir = DMA_TO_DEVICE,
> +             .ee_mask = MHI_CH_EE_SBL,
> +             .pollcfg = 0,
> +             .doorbell = MHI_DB_BRST_DISABLE,
> +             .lpm_notify = false,
> +             .offload_channel = false,
> +             .doorbell_mode_switch = false,
> +             .auto_queue = false,
> +             .wake_capable = false,
> +     },
> +     {
> +             .name = "QAIC_SAHARA",
> +             .num = 3,
> +             .num_elements = 32,
> +             .local_elements = 0,
> +             .event_ring = 0,
> +             .dir = DMA_FROM_DEVICE,
> +             .ee_mask = MHI_CH_EE_SBL,
> +             .pollcfg = 0,
> +             .doorbell = MHI_DB_BRST_DISABLE,
> +             .lpm_notify = false,
> +             .offload_channel = false,
> +             .doorbell_mode_switch = false,
> +             .auto_queue = 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,
> +             .auto_queue = 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,
> +             .auto_queue = 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,
> +             .auto_queue = 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,
> +             .auto_queue = false,
> +             .wake_capable = false,
> +     },
> +     {
> +             .name = "QAIC_LOGGING",
> +             .num = 12,
> +             .num_elements = 32,
> +             .local_elements = 0,
> +             .event_ring = 0,
> +             .dir = DMA_TO_DEVICE,
> +             .ee_mask = MHI_CH_EE_SBL,
> +             .pollcfg = 0,
> +             .doorbell = MHI_DB_BRST_DISABLE,
> +             .lpm_notify = false,
> +             .offload_channel = false,
> +             .doorbell_mode_switch = false,
> +             .auto_queue = false,
> +             .wake_capable = false,
> +     },
> +     {
> +             .name = "QAIC_LOGGING",
> +             .num = 13,
> +             .num_elements = 32,
> +             .local_elements = 0,
> +             .event_ring = 0,
> +             .dir = DMA_FROM_DEVICE,
> +             .ee_mask = MHI_CH_EE_SBL,
> +             .pollcfg = 0,
> +             .doorbell = MHI_DB_BRST_DISABLE,
> +             .lpm_notify = false,
> +             .offload_channel = false,
> +             .doorbell_mode_switch = false,
> +             .auto_queue = false,
> +             .wake_capable = false,
> +     },
> +     {
> +             .name = "QAIC_STATUS",
> +             .num = 14,
> +             .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,
> +             .auto_queue = false,
> +             .wake_capable = false,
> +     },
> +     {
> +             .name = "QAIC_STATUS",
> +             .num = 15,
> +             .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,
> +             .auto_queue = 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,
> +             .auto_queue = 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,
> +             .auto_queue = false,
> +             .wake_capable = false,
> +     },
> +     {
> +             .name = "QAIC_TIMESYNC_PERIODIC",
> +             .num = 22,
> +             .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,
> +             .auto_queue = false,
> +             .wake_capable = false,
> +     },
> +     {
> +             .name = "QAIC_TIMESYNC_PERIODIC",
> +             .num = 23,
> +             .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,
> +             .auto_queue = 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,
> +             .auto_queue = 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,
> +             .auto_queue = true,
> +             .wake_capable = false,
> +     },
> +};
> +
>  static struct mhi_event_config aic100_events[] = {
>       {
>               .num_elements = 32,
> @@ -454,16 +750,44 @@ static struct mhi_event_config aic100_events[] = {
>       },
>  };
>  
> -static struct mhi_controller_config aic100_config = {
> -     .max_channels = 128,
> -     .timeout_ms = 0, /* controlled by mhi_timeout */
> -     .buf_len = 0,
> -     .num_channels = ARRAY_SIZE(aic100_channels),
> -     .ch_cfg = aic100_channels,
> -     .num_events = ARRAY_SIZE(aic100_events),
> -     .event_cfg = aic100_events,
> -     .use_bounce_buf = false,
> -     .m2_no_db = false,
> +static struct mhi_event_config aic200_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,
> +             .timeout_ms = 0, /* controlled by mhi_timeout */
> +             .buf_len = 0,
> +             .num_channels = ARRAY_SIZE(aic100_channels),
> +             .ch_cfg = aic100_channels,
> +             .num_events = ARRAY_SIZE(aic100_events),
> +             .event_cfg = aic100_events,
> +             .use_bounce_buf = false,
> +             .m2_no_db = false,
> +     },
> +     [FAMILY_AIC200] = {
> +             .max_channels = 128,
> +             .timeout_ms = 0, /* controlled by mhi_timeout */
> +             .buf_len = 0,
> +             .num_channels = ARRAY_SIZE(aic200_channels),
> +             .ch_cfg = aic200_channels,
> +             .num_events = ARRAY_SIZE(aic200_events),
> +             .event_cfg = aic200_events,
> +             .use_bounce_buf = false,
> +             .m2_no_db = false,
> +     },
>  };
>  
>  static int mhi_read_reg(struct mhi_controller *mhi_cntrl, void __iomem 
> *addr, u32 *out)
> @@ -545,8 +869,9 @@ static int mhi_reset_and_async_power_up(struct 
> mhi_controller *mhi_cntrl)
>  }
>  
>  struct mhi_controller *qaic_mhi_register_controller(struct pci_dev *pci_dev, 
> void __iomem *mhi_bar,
> -                                                 int mhi_irq, bool 
> shared_msi)
> +                                                 int mhi_irq, bool 
> shared_msi, int family)
>  {
> +     struct mhi_controller_config mhi_config = mhi_cntrl_configs[family];
>       struct mhi_controller *mhi_cntrl;
>       int ret;
>  
> @@ -581,11 +906,18 @@ struct mhi_controller 
> *qaic_mhi_register_controller(struct pci_dev *pci_dev, voi
>       if (shared_msi) /* MSI shared with data path, no IRQF_NO_SUSPEND */
>               mhi_cntrl->irq_flags = IRQF_SHARED;
>  
> -     mhi_cntrl->fw_image = "qcom/aic100/sbl.bin";
> +     mhi_cntrl->fw_image = fw_image_paths[family];
> +
> +     if (family == FAMILY_AIC200) {
> +             mhi_cntrl->name = "AIC200";
> +             mhi_cntrl->seg_len = SZ_512K;
> +     } else {
> +             mhi_cntrl->name = "AIC100";
> +     }
>  
>       /* use latest configured timeout */
> -     aic100_config.timeout_ms = mhi_timeout_ms;
> -     ret = mhi_register_controller(mhi_cntrl, &aic100_config);
> +     mhi_config.timeout_ms = mhi_timeout_ms;
> +     ret = mhi_register_controller(mhi_cntrl, &mhi_config);
>       if (ret) {
>               pci_err(pci_dev, "mhi_register_controller failed %d\n", ret);
>               return ERR_PTR(ret);
> diff --git a/drivers/accel/qaic/mhi_controller.h 
> b/drivers/accel/qaic/mhi_controller.h
> index 500e7f4af2af..8939f6ae185e 100644
> --- a/drivers/accel/qaic/mhi_controller.h
> +++ b/drivers/accel/qaic/mhi_controller.h
> @@ -8,7 +8,7 @@
>  #define MHICONTROLLERQAIC_H_
>  
>  struct mhi_controller *qaic_mhi_register_controller(struct pci_dev *pci_dev, 
> void __iomem *mhi_bar,
> -                                                 int mhi_irq, bool 
> shared_msi);
> +                                                 int mhi_irq, bool 
> shared_msi, int family);
>  void qaic_mhi_free_controller(struct mhi_controller *mhi_cntrl, bool 
> link_up);
>  void qaic_mhi_start_reset(struct mhi_controller *mhi_cntrl);
>  void qaic_mhi_reset_done(struct mhi_controller *mhi_cntrl);
> diff --git a/drivers/accel/qaic/qaic.h b/drivers/accel/qaic/qaic.h
> index cf97fd9a7e70..0dbb8e32e4b9 100644
> --- a/drivers/accel/qaic/qaic.h
> +++ b/drivers/accel/qaic/qaic.h
> @@ -34,6 +34,7 @@
>  
>  enum aic_families {
>       FAMILY_AIC100,
> +     FAMILY_AIC200,
>       FAMILY_MAX,
>  };
>  
> diff --git a/drivers/accel/qaic/qaic_drv.c b/drivers/accel/qaic/qaic_drv.c
> index 4e63e475b389..3b415e2c9431 100644
> --- a/drivers/accel/qaic/qaic_drv.c
> +++ b/drivers/accel/qaic/qaic_drv.c
> @@ -36,6 +36,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 QAIC_NAME                    "qaic"
>  #define QAIC_DESC                    "Qualcomm Cloud AI Accelerators"
>  #define CNTL_MAJOR                   5
> @@ -66,6 +67,13 @@ static const struct qaic_device_config aic100_config = {
>       .dbc_bar_idx = 2,
>  };
>  
> +static const struct qaic_device_config aic200_config = {
> +     .family = FAMILY_AIC200,
> +     .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");
> @@ -568,7 +576,7 @@ static int qaic_pci_probe(struct pci_dev *pdev, const 
> struct pci_device_id *id)
>               return ret;
>  
>       qdev->mhi_cntrl = qaic_mhi_register_controller(pdev, qdev->bar_mhi, 
> mhi_irq,
> -                                                    qdev->single_msi);
> +                                                    qdev->single_msi, 
> config->family);
>       if (IS_ERR(qdev->mhi_cntrl)) {
>               ret = PTR_ERR(qdev->mhi_cntrl);
>               qaic_destroy_drm_device(qdev, QAIC_NO_PARTITION);
> @@ -637,6 +645,7 @@ static struct mhi_driver qaic_mhi_driver = {
>  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), },
>       { }
>  };
>  MODULE_DEVICE_TABLE(pci, qaic_ids);
> diff --git a/drivers/accel/qaic/sahara.c b/drivers/accel/qaic/sahara.c
> index 09c8b055aa81..3ebcc1f7ff58 100644
> --- a/drivers/accel/qaic/sahara.c
> +++ b/drivers/accel/qaic/sahara.c
> @@ -188,6 +188,34 @@ static const char * const aic100_image_table[] = {
>       [10] = "qcom/aic100/fw10.bin",
>  };
>  
> +static const char * const aic200_image_table[] = {
> +     [5]  = "qcom/aic200/uefi.elf",
> +     [12] = "qcom/aic200/aic200-nsp.bin",
> +     [23] = "qcom/aic200/aop.mbn",
> +     [32] = "qcom/aic200/tz.mbn",
> +     [33] = "qcom/aic200/hypvm.mbn",
> +     [39] = "qcom/aic200/aic200_abl.elf",
> +     [40] = "qcom/aic200/apdp.mbn",
> +     [41] = "qcom/aic200/devcfg.mbn",
> +     [42] = "qcom/aic200/sec.elf",
> +     [43] = "qcom/aic200/aic200-hlos.elf",
> +     [49] = "qcom/aic200/shrm.elf",
> +     [50] = "qcom/aic200/cpucp.elf",
> +     [51] = "qcom/aic200/aop_devcfg.mbn",
> +     [57] = "qcom/aic200/cpucp_dtbs.elf",
> +     [62] = "qcom/aic200/uefi_dtbs.elf",
> +     [63] = "qcom/aic200/xbl_ac_config.mbn",
> +     [64] = "qcom/aic200/tz_ac_config.mbn",
> +     [65] = "qcom/aic200/hyp_ac_config.mbn",
> +     [66] = "qcom/aic200/pdp.elf",
> +     [67] = "qcom/aic200/pdp_cdb.elf",
> +     [68] = "qcom/aic200/sdi.mbn",
> +     [69] = "qcom/aic200/dcd.mbn",
> +     [73] = "qcom/aic200/gearvm.mbn",
> +     [74] = "qcom/aic200/sti.bin",
> +     [75] = "qcom/aic200/pvs.bin",
> +};
> +
>  static int sahara_find_image(struct sahara_context *context, u32 image_id)
>  {
>       int ret;
> @@ -748,8 +776,15 @@ static int sahara_mhi_probe(struct mhi_device *mhi_dev, 
> const struct mhi_device_
>       context->mhi_dev = mhi_dev;
>       INIT_WORK(&context->fw_work, sahara_processing);
>       INIT_WORK(&context->dump_work, sahara_dump_processing);
> -     context->image_table = aic100_image_table;
> -     context->table_size = ARRAY_SIZE(aic100_image_table);
> +
> +     if (!strcmp(mhi_dev->mhi_cntrl->name, "AIC200")) {
> +             context->image_table = aic200_image_table;
> +             context->table_size = ARRAY_SIZE(aic200_image_table);
> +     } else {
> +             context->image_table = aic100_image_table;
> +             context->table_size = ARRAY_SIZE(aic100_image_table);
> +     }
> +
>       context->active_image_id = SAHARA_IMAGE_ID_NONE;
>       dev_set_drvdata(&mhi_dev->dev, context);
>  
> -- 
> 2.34.1
> 

-- 
மணிவண்ணன் சதாசிவம்

Reply via email to