From patchwork Thu Sep 21 20:43:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Chautru, Nicolas" X-Patchwork-Id: 131814 X-Patchwork-Delegate: maxime.coquelin@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id D7D9B4260E; Thu, 21 Sep 2023 22:47:48 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 30FF440DDA; Thu, 21 Sep 2023 22:47:08 +0200 (CEST) Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.100]) by mails.dpdk.org (Postfix) with ESMTP id 977D8402EF for ; Thu, 21 Sep 2023 22:47:02 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695329222; x=1726865222; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=LNkgQASf5igpVjeJpsvKqR57ThBsJ6/wYIP6Veb2anY=; b=dEMKyCpsCpZH9GzMFkFjbsEmgSimFtvGrGrfYO/Pb3YwEsEQAI9hjfi/ NJvVfpp5sUHka4pNu1XiDRGLKAEjeluUJqTsdaTCKzO54EpOQVFGrd6Sb 3uN5zWY7Yx+zL3JQQFeXlo57sadIpySbnOUQDGwMHU2v0nZAvqUll85g7 FIU17RWPfIduGlJIPrYr2Lidpdm6G8hiKZQazpcorfUMNq/u5/1PpEeRi isCyUByYm5Jll4h3A5t/hjN8FrOaKTdnW2FMFBxcNHRbJODqu9vGCK5zq 6OyFM0ufmm/DvYYaD5y5ffFhJu+SRpdITnWS5oaIed7LORCRQUImAsuja w==; X-IronPort-AV: E=McAfee;i="6600,9927,10840"; a="447138129" X-IronPort-AV: E=Sophos;i="6.03,166,1694761200"; d="scan'208";a="447138129" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Sep 2023 13:47:01 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10840"; a="696907263" X-IronPort-AV: E=Sophos;i="6.03,166,1694761200"; d="scan'208";a="696907263" Received: from spr-npg-bds1-eec2.sn.intel.com (HELO spr-npg-bds1-eec2..) ([10.233.181.123]) by orsmga003.jf.intel.com with ESMTP; 21 Sep 2023 13:47:01 -0700 From: Nicolas Chautru To: dev@dpdk.org, maxime.coquelin@redhat.com Cc: hemant.agrawal@nxp.com, david.marchand@redhat.com, hernan.vargas@intel.com, Nicolas Chautru Subject: [PATCH v2 7/7] baseband/acc: add configure helper for VRB2 Date: Thu, 21 Sep 2023 20:43:49 +0000 Message-Id: <20230921204349.3285318-8-nicolas.chautru@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230921204349.3285318-1-nicolas.chautru@intel.com> References: <20230921204349.3285318-1-nicolas.chautru@intel.com> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org This allows to configure the VRB2 device using a companion configuration function within the DPDK bbdev-test environment. Signed-off-by: Nicolas Chautru --- drivers/baseband/acc/acc100_pmd.h | 2 + drivers/baseband/acc/acc_common.h | 7 + drivers/baseband/acc/rte_acc100_pmd.c | 6 +- drivers/baseband/acc/rte_vrb_pmd.c | 322 ++++++++++++++++++++++++++ drivers/baseband/acc/vrb_cfg.h | 16 ++ 5 files changed, 352 insertions(+), 1 deletion(-) diff --git a/drivers/baseband/acc/acc100_pmd.h b/drivers/baseband/acc/acc100_pmd.h index a48298650c..5a8965fa53 100644 --- a/drivers/baseband/acc/acc100_pmd.h +++ b/drivers/baseband/acc/acc100_pmd.h @@ -34,6 +34,8 @@ #define ACC100_VENDOR_ID (0x8086) #define ACC100_PF_DEVICE_ID (0x0d5c) #define ACC100_VF_DEVICE_ID (0x0d5d) +#define VRB1_PF_DEVICE_ID (0x57C0) +#define VRB2_PF_DEVICE_ID (0x57C2) /* Values used in writing to the registers */ #define ACC100_REG_IRQ_EN_ALL 0x1FF83FF /* Enable all interrupts */ diff --git a/drivers/baseband/acc/acc_common.h b/drivers/baseband/acc/acc_common.h index b71292af94..52e537b747 100644 --- a/drivers/baseband/acc/acc_common.h +++ b/drivers/baseband/acc/acc_common.h @@ -1480,6 +1480,13 @@ get_num_cbs_in_tb_ldpc_enc(struct rte_bbdev_op_ldpc_enc *ldpc_enc) return cbs_in_tb; } +static inline void +acc_reg_fast_write(struct acc_device *d, uint32_t offset, uint32_t value) +{ + void *reg_addr = RTE_PTR_ADD(d->mmio_base, offset); + mmio_write(reg_addr, value); +} + #ifdef RTE_LIBRTE_BBDEV_DEBUG static inline void acc_memdump(const char *string, void *buf, uint16_t bytes) diff --git a/drivers/baseband/acc/rte_acc100_pmd.c b/drivers/baseband/acc/rte_acc100_pmd.c index 7f8d05b5a9..699a227d13 100644 --- a/drivers/baseband/acc/rte_acc100_pmd.c +++ b/drivers/baseband/acc/rte_acc100_pmd.c @@ -5187,6 +5187,10 @@ rte_acc_configure(const char *dev_name, struct rte_acc_conf *conf) return acc100_configure(dev_name, conf); else if (pci_dev->id.device_id == ACC101_PF_DEVICE_ID) return acc101_configure(dev_name, conf); - else + else if (pci_dev->id.device_id == VRB1_PF_DEVICE_ID) return vrb1_configure(dev_name, conf); + else if (pci_dev->id.device_id == VRB2_PF_DEVICE_ID) + return vrb2_configure(dev_name, conf); + + return -ENXIO; } diff --git a/drivers/baseband/acc/rte_vrb_pmd.c b/drivers/baseband/acc/rte_vrb_pmd.c index a787592ec9..cdf394de01 100644 --- a/drivers/baseband/acc/rte_vrb_pmd.c +++ b/drivers/baseband/acc/rte_vrb_pmd.c @@ -5071,3 +5071,325 @@ vrb1_configure(const char *dev_name, struct rte_acc_conf *conf) rte_bbdev_log_debug("PF Tip configuration complete for %s", dev_name); return 0; } + + +/* Initial configuration of a VRB2 device prior to running configure(). */ +int +vrb2_configure(const char *dev_name, struct rte_acc_conf *conf) +{ + rte_bbdev_log(INFO, "vrb2_configure"); + uint32_t value, address, status; + int qg_idx, template_idx, vf_idx, acc, i, aq_reg, static_allocation, numEngines; + int numQgs, numQqsAcc, totalQgs; + int qman_func_id[8] = {0, 2, 1, 3, 4, 5, 0, 0}; + struct rte_bbdev *bbdev = rte_bbdev_get_named_dev(dev_name); + int rlim, alen, timestamp; + + /* Compile time checks. */ + RTE_BUILD_BUG_ON(sizeof(struct acc_dma_req_desc) != 256); + RTE_BUILD_BUG_ON(sizeof(union acc_dma_desc) != 256); + RTE_BUILD_BUG_ON(sizeof(struct acc_fcw_td) != 24); + RTE_BUILD_BUG_ON(sizeof(struct acc_fcw_te) != 32); + + if (bbdev == NULL) { + rte_bbdev_log(ERR, + "Invalid dev_name (%s), or device is not yet initialised", + dev_name); + return -ENODEV; + } + struct acc_device *d = bbdev->data->dev_private; + + /* Store configuration. */ + rte_memcpy(&d->acc_conf, conf, sizeof(d->acc_conf)); + + /* Explicitly releasing AXI as this may be stopped after PF FLR/BME. */ + address = VRB2_PfDmaAxiControl; + value = 1; + acc_reg_write(d, address, value); + + /* Set the fabric mode. */ + address = VRB2_PfFabricM2iBufferReg; + value = VRB2_FABRIC_MODE; + acc_reg_write(d, address, value); + + /* Set default descriptor signature. */ + address = VRB2_PfDmaDescriptorSignature; + value = 0; + acc_reg_write(d, address, value); + + /* Enable the Error Detection in DMA. */ + value = VRB2_CFG_DMA_ERROR; + address = VRB2_PfDmaErrorDetectionEn; + acc_reg_write(d, address, value); + + /* AXI Cache configuration. */ + value = VRB2_CFG_AXI_CACHE; + address = VRB2_PfDmaAxcacheReg; + acc_reg_write(d, address, value); + + /* AXI Response configuration. */ + acc_reg_write(d, VRB2_PfDmaCfgRrespBresp, 0x0); + + /* Default DMA Configuration (Qmgr Enabled) */ + acc_reg_write(d, VRB2_PfDmaConfig0Reg, 0); + acc_reg_write(d, VRB2_PfDmaQmanenSelect, 0xFFFFFFFF); + acc_reg_write(d, VRB2_PfDmaQmanen, 0); + + /* Default RLIM/ALEN configuration. */ + rlim = 0; + alen = 3; + timestamp = 0; + address = VRB2_PfDmaConfig1Reg; + value = (1 << 31) + (rlim << 8) + (timestamp << 6) + alen; + acc_reg_write(d, address, value); + + /* Default FFT configuration. */ + for (template_idx = 0; template_idx < VRB2_FFT_NUM; template_idx++) { + acc_reg_write(d, VRB2_PfFftConfig0 + template_idx * 0x1000, VRB2_FFT_CFG_0); + acc_reg_write(d, VRB2_PfFftParityMask8 + template_idx * 0x1000, VRB2_FFT_ECC); + } + + /* Configure DMA Qmanager addresses. */ + address = VRB2_PfDmaQmgrAddrReg; + value = VRB2_PfQmgrEgressQueuesTemplate; + acc_reg_write(d, address, value); + + /* ===== Qmgr Configuration ===== */ + /* Configuration of the AQueue Depth QMGR_GRP_0_DEPTH_LOG2 for UL. */ + totalQgs = conf->q_ul_4g.num_qgroups + conf->q_ul_5g.num_qgroups + + conf->q_dl_4g.num_qgroups + conf->q_dl_5g.num_qgroups + + conf->q_fft.num_qgroups + conf->q_mld.num_qgroups; + for (qg_idx = 0; qg_idx < VRB2_NUM_QGRPS; qg_idx++) { + address = VRB2_PfQmgrDepthLog2Grp + ACC_BYTES_IN_WORD * qg_idx; + value = aqDepth(qg_idx, conf); + acc_reg_write(d, address, value); + address = VRB2_PfQmgrTholdGrp + ACC_BYTES_IN_WORD * qg_idx; + value = (1 << 16) + (1 << (aqDepth(qg_idx, conf) - 1)); + acc_reg_write(d, address, value); + } + + /* Template Priority in incremental order. */ + for (template_idx = 0; template_idx < ACC_NUM_TMPL; template_idx++) { + address = VRB2_PfQmgrGrpTmplateReg0Indx + ACC_BYTES_IN_WORD * template_idx; + value = ACC_TMPL_PRI_0; + acc_reg_write(d, address, value); + address = VRB2_PfQmgrGrpTmplateReg1Indx + ACC_BYTES_IN_WORD * template_idx; + value = ACC_TMPL_PRI_1; + acc_reg_write(d, address, value); + address = VRB2_PfQmgrGrpTmplateReg2Indx + ACC_BYTES_IN_WORD * template_idx; + value = ACC_TMPL_PRI_2; + acc_reg_write(d, address, value); + address = VRB2_PfQmgrGrpTmplateReg3Indx + ACC_BYTES_IN_WORD * template_idx; + value = ACC_TMPL_PRI_3; + acc_reg_write(d, address, value); + address = VRB2_PfQmgrGrpTmplateReg4Indx + ACC_BYTES_IN_WORD * template_idx; + value = ACC_TMPL_PRI_4; + acc_reg_write(d, address, value); + address = VRB2_PfQmgrGrpTmplateReg5Indx + ACC_BYTES_IN_WORD * template_idx; + value = ACC_TMPL_PRI_5; + acc_reg_write(d, address, value); + address = VRB2_PfQmgrGrpTmplateReg6Indx + ACC_BYTES_IN_WORD * template_idx; + value = ACC_TMPL_PRI_6; + acc_reg_write(d, address, value); + address = VRB2_PfQmgrGrpTmplateReg7Indx + ACC_BYTES_IN_WORD * template_idx; + value = ACC_TMPL_PRI_7; + acc_reg_write(d, address, value); + } + + address = VRB2_PfQmgrGrpPriority; + value = VRB2_CFG_QMGR_HI_P; + acc_reg_write(d, address, value); + + /* Template Configuration. */ + for (template_idx = 0; template_idx < ACC_NUM_TMPL; template_idx++) { + value = 0; + address = VRB2_PfQmgrGrpTmplateEnRegIndx + ACC_BYTES_IN_WORD * template_idx; + acc_reg_write(d, address, value); + } + /* 4GUL */ + numQgs = conf->q_ul_4g.num_qgroups; + numQqsAcc = 0; + value = 0; + for (qg_idx = numQqsAcc; qg_idx < (numQgs + numQqsAcc); qg_idx++) + value |= (1 << qg_idx); + for (template_idx = VRB2_SIG_UL_4G; template_idx <= VRB2_SIG_UL_4G_LAST; + template_idx++) { + address = VRB2_PfQmgrGrpTmplateEnRegIndx + ACC_BYTES_IN_WORD * template_idx; + acc_reg_write(d, address, value); + } + /* 5GUL */ + numQqsAcc += numQgs; + numQgs = conf->q_ul_5g.num_qgroups; + value = 0; + numEngines = 0; + for (qg_idx = numQqsAcc; qg_idx < (numQgs + numQqsAcc); qg_idx++) + value |= (1 << qg_idx); + for (template_idx = VRB2_SIG_UL_5G; template_idx <= VRB2_SIG_UL_5G_LAST; + template_idx++) { + /* Check engine power-on status. */ + address = VRB2_PfFecUl5gIbDebug0Reg + ACC_ENGINE_OFFSET * template_idx; + status = (acc_reg_read(d, address) >> 4) & 0x7; + address = VRB2_PfQmgrGrpTmplateEnRegIndx + ACC_BYTES_IN_WORD * template_idx; + if (status == 1) { + acc_reg_write(d, address, value); + numEngines++; + } else + acc_reg_write(d, address, 0); + } + rte_bbdev_log(INFO, "Number of 5GUL engines %d", numEngines); + /* 4GDL */ + numQqsAcc += numQgs; + numQgs = conf->q_dl_4g.num_qgroups; + value = 0; + for (qg_idx = numQqsAcc; qg_idx < (numQgs + numQqsAcc); qg_idx++) + value |= (1 << qg_idx); + for (template_idx = VRB2_SIG_DL_4G; template_idx <= VRB2_SIG_DL_4G_LAST; + template_idx++) { + address = VRB2_PfQmgrGrpTmplateEnRegIndx + ACC_BYTES_IN_WORD * template_idx; + acc_reg_write(d, address, value); + } + /* 5GDL */ + numQqsAcc += numQgs; + numQgs = conf->q_dl_5g.num_qgroups; + value = 0; + for (qg_idx = numQqsAcc; qg_idx < (numQgs + numQqsAcc); qg_idx++) + value |= (1 << qg_idx); + for (template_idx = VRB2_SIG_DL_5G; template_idx <= VRB2_SIG_DL_5G_LAST; + template_idx++) { + address = VRB2_PfQmgrGrpTmplateEnRegIndx + ACC_BYTES_IN_WORD * template_idx; + acc_reg_write(d, address, value); + } + /* FFT */ + numQqsAcc += numQgs; + numQgs = conf->q_fft.num_qgroups; + value = 0; + for (qg_idx = numQqsAcc; qg_idx < (numQgs + numQqsAcc); qg_idx++) + value |= (1 << qg_idx); + for (template_idx = VRB2_SIG_FFT; template_idx <= VRB2_SIG_FFT_LAST; + template_idx++) { + address = VRB2_PfQmgrGrpTmplateEnRegIndx + ACC_BYTES_IN_WORD * template_idx; + acc_reg_write(d, address, value); + } + /* MLD */ + numQqsAcc += numQgs; + numQgs = conf->q_mld.num_qgroups; + value = 0; + for (qg_idx = numQqsAcc; qg_idx < (numQgs + numQqsAcc); qg_idx++) + value |= (1 << qg_idx); + for (template_idx = VRB2_SIG_MLD; template_idx <= VRB2_SIG_MLD_LAST; + template_idx++) { + address = VRB2_PfQmgrGrpTmplateEnRegIndx + + ACC_BYTES_IN_WORD * template_idx; + acc_reg_write(d, address, value); + } + + /* Queue Group Function mapping. */ + for (i = 0; i < 4; i++) { + value = 0; + for (qg_idx = 0; qg_idx < ACC_NUM_QGRPS_PER_WORD; qg_idx++) { + acc = accFromQgid(qg_idx + i * ACC_NUM_QGRPS_PER_WORD, conf); + value |= qman_func_id[acc] << (qg_idx * 4); + } + acc_reg_write(d, VRB2_PfQmgrGrpFunction0 + i * ACC_BYTES_IN_WORD, value); + } + + /* Configuration of the Arbitration QGroup depth to 1. */ + for (qg_idx = 0; qg_idx < VRB2_NUM_QGRPS; qg_idx++) { + address = VRB2_PfQmgrArbQDepthGrp + ACC_BYTES_IN_WORD * qg_idx; + value = 0; + acc_reg_write(d, address, value); + } + + static_allocation = 1; + if (static_allocation == 1) { + /* This pointer to ARAM (512kB) is shifted by 2 (4B per register). */ + uint32_t aram_address = 0; + for (qg_idx = 0; qg_idx < totalQgs; qg_idx++) { + for (vf_idx = 0; vf_idx < conf->num_vf_bundles; vf_idx++) { + address = VRB2_PfQmgrVfBaseAddr + vf_idx + * ACC_BYTES_IN_WORD + qg_idx + * ACC_BYTES_IN_WORD * 64; + value = aram_address; + acc_reg_fast_write(d, address, value); + /* Offset ARAM Address for next memory bank - increment of 4B. */ + aram_address += aqNum(qg_idx, conf) * + (1 << aqDepth(qg_idx, conf)); + } + } + if (aram_address > VRB2_WORDS_IN_ARAM_SIZE) { + rte_bbdev_log(ERR, "ARAM Configuration not fitting %d %d\n", + aram_address, VRB2_WORDS_IN_ARAM_SIZE); + return -EINVAL; + } + } else { + /* Dynamic Qmgr allocation. */ + acc_reg_write(d, VRB2_PfQmgrAramAllocEn, 1); + acc_reg_write(d, VRB2_PfQmgrAramAllocSetupN0, 0x1000); + acc_reg_write(d, VRB2_PfQmgrAramAllocSetupN1, 0); + acc_reg_write(d, VRB2_PfQmgrAramAllocSetupN2, 0); + acc_reg_write(d, VRB2_PfQmgrAramAllocSetupN3, 0); + acc_reg_write(d, VRB2_PfQmgrSoftReset, 1); + acc_reg_write(d, VRB2_PfQmgrSoftReset, 0); + } + + /* ==== HI Configuration ==== */ + + /* No Info Ring/MSI by default. */ + address = VRB2_PfHiInfoRingIntWrEnRegPf; + value = 0; + acc_reg_write(d, address, value); + address = VRB2_PfHiCfgMsiIntWrEnRegPf; + value = 0xFFFFFFFF; + acc_reg_write(d, address, value); + /* Prevent Block on Transmit Error. */ + address = VRB2_PfHiBlockTransmitOnErrorEn; + value = 0; + acc_reg_write(d, address, value); + /* Prevents to drop MSI */ + address = VRB2_PfHiMsiDropEnableReg; + value = 0; + acc_reg_write(d, address, value); + /* Set the PF Mode register */ + address = VRB2_PfHiPfMode; + value = ((conf->pf_mode_en) ? ACC_PF_VAL : 0) | 0x1F07F0; + acc_reg_write(d, address, value); + /* Explicitly releasing AXI after PF Mode. */ + acc_reg_write(d, VRB2_PfDmaAxiControl, 1); + + /* QoS overflow init. */ + value = 1; + address = VRB2_PfQosmonAEvalOverflow0; + acc_reg_write(d, address, value); + address = VRB2_PfQosmonBEvalOverflow0; + acc_reg_write(d, address, value); + + /* Enabling AQueues through the Queue hierarchy. */ + unsigned int en_bitmask[VRB2_AQ_REG_NUM]; + for (vf_idx = 0; vf_idx < VRB2_NUM_VFS; vf_idx++) { + for (qg_idx = 0; qg_idx < VRB2_NUM_QGRPS; qg_idx++) { + for (aq_reg = 0; aq_reg < VRB2_AQ_REG_NUM; aq_reg++) + en_bitmask[aq_reg] = 0; + if (vf_idx < conf->num_vf_bundles && qg_idx < totalQgs) { + for (aq_reg = 0; aq_reg < VRB2_AQ_REG_NUM; aq_reg++) { + if (aqNum(qg_idx, conf) >= 16 * (aq_reg + 1)) + en_bitmask[aq_reg] = 0xFFFF; + else if (aqNum(qg_idx, conf) <= 16 * aq_reg) + en_bitmask[aq_reg] = 0x0; + else + en_bitmask[aq_reg] = (1 << (aqNum(qg_idx, + conf) - aq_reg * 16)) - 1; + } + } + for (aq_reg = 0; aq_reg < VRB2_AQ_REG_NUM; aq_reg++) { + address = VRB2_PfQmgrAqEnableVf + vf_idx * 16 + aq_reg * 4; + value = (qg_idx << 16) + en_bitmask[aq_reg]; + acc_reg_fast_write(d, address, value); + } + } + } + + rte_bbdev_log(INFO, + "VRB2 basic config complete for %s - pf_bb_config should ideally be used instead", + dev_name); + return 0; +} diff --git a/drivers/baseband/acc/vrb_cfg.h b/drivers/baseband/acc/vrb_cfg.h index e3c8902b46..79487c4e04 100644 --- a/drivers/baseband/acc/vrb_cfg.h +++ b/drivers/baseband/acc/vrb_cfg.h @@ -29,4 +29,20 @@ int vrb1_configure(const char *dev_name, struct rte_acc_conf *conf); +/** + * Configure a VRB2 device. + * + * @param dev_name + * The name of the device. This is the short form of PCI BDF, e.g. 00:01.0. + * It can also be retrieved for a bbdev device from the dev_name field in the + * rte_bbdev_info structure returned by rte_bbdev_info_get(). + * @param conf + * Configuration to apply to VRB2 HW. + * + * @return + * Zero on success, negative value on failure. + */ +int +vrb2_configure(const char *dev_name, struct rte_acc_conf *conf); + #endif /* _VRB_CFG_H_ */