From 3f28677a81584700732eebfcc8ae1ff21fa8945b Mon Sep 17 00:00:00 2001 From: Hemant Agrawal Date: Fri, 11 Jan 2019 12:24:38 +0000 Subject: [PATCH] bus/fslmc: add dynamic config for memback portal mode Add flag in portal init to adjust the qbman memory type, to decide between legacy portal mode or newly introduced memory backed portals. Signed-off-by: Roy Pledge Signed-off-by: Youri Querry Signed-off-by: Hemant Agrawal --- drivers/bus/fslmc/portal/dpaa2_hw_dpio.c | 2 + .../bus/fslmc/qbman/include/fsl_qbman_base.h | 11 +++- drivers/bus/fslmc/qbman/qbman_portal.c | 52 +++++++++++-------- drivers/bus/fslmc/qbman/qbman_sys.h | 20 ++++--- 4 files changed, 53 insertions(+), 32 deletions(-) diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c index ba2e28ce1f..37723a0944 100644 --- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c +++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c @@ -509,6 +509,8 @@ dpaa2_create_dpio_device(int vdev_fd, p_des.cinh_bar = (void *)(dpio_dev->qbman_portal_ci_paddr); p_des.irq = -1; p_des.qman_version = attr.qbman_version; + p_des.eqcr_mode = qman_eqcr_vb_ring; + p_des.cena_access_mode = qman_cena_fastest_access; dpio_dev->sw_portal = qbman_swp_init(&p_des); if (dpio_dev->sw_portal == NULL) { diff --git a/drivers/bus/fslmc/qbman/include/fsl_qbman_base.h b/drivers/bus/fslmc/qbman/include/fsl_qbman_base.h index bb60a98f9a..48bdaafa49 100644 --- a/drivers/bus/fslmc/qbman/include/fsl_qbman_base.h +++ b/drivers/bus/fslmc/qbman/include/fsl_qbman_base.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause * * Copyright (C) 2014 Freescale Semiconductor, Inc. + * Copyright 2017-2018 NXP * */ #ifndef _FSL_QBMAN_BASE_H @@ -33,7 +34,12 @@ struct qbman_block_desc { enum qbman_eqcr_mode { qman_eqcr_vb_ring = 2, /* Valid bit, with eqcr in ring mode */ - qman_eqcr_vb_array, /* Valid bit, with eqcr in array mode */ + qman_eqcr_vb_array, /* Valid bit, with eqcr in array mode */ +}; + +enum qbman_cena_access_mode { + qman_cena_fastest_access = 0, /* Use memory backed node if available */ + qman_cena_direct_access, /* Use direct access to the CENA region */ }; /** @@ -46,6 +52,8 @@ enum qbman_eqcr_mode { * @qman_version: the qman version. * @eqcr_mode: Select the eqcr mode, currently only valid bit ring mode and * valid bit array mode are supported. + * @cena_access_mode: Mode used to access the CENA region, direct + * or memory backed. * * Descriptor for a QBMan software portal, expressed in terms that make sense to * the user context. Ie. on MC, this information is likely to be true-physical, @@ -62,6 +70,7 @@ struct qbman_swp_desc { int idx; uint32_t qman_version; enum qbman_eqcr_mode eqcr_mode; + enum qbman_cena_access_mode cena_access_mode; }; /* Driver object for managing a QBMan portal */ diff --git a/drivers/bus/fslmc/qbman/qbman_portal.c b/drivers/bus/fslmc/qbman/qbman_portal.c index 2f572a08b1..08bfdc9f8f 100644 --- a/drivers/bus/fslmc/qbman/qbman_portal.c +++ b/drivers/bus/fslmc/qbman/qbman_portal.c @@ -194,7 +194,8 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d) p->sdq |= qbman_sdqcr_dct_prio_ics << QB_SDQCR_DCT_SHIFT; p->sdq |= qbman_sdqcr_fc_up_to_3 << QB_SDQCR_FC_SHIFT; p->sdq |= QMAN_SDQCR_TOKEN << QB_SDQCR_TOK_SHIFT; - if ((d->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) + if ((d->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000 + && (d->cena_access_mode == qman_cena_fastest_access)) p->mr.valid_bit = QB_VALID_BIT; atomic_set(&p->vdq.busy, 1); @@ -233,7 +234,8 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d) qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_SDQCR, 0); p->eqcr.pi_ring_size = 8; - if ((qman_version & 0xFFFF0000) >= QMAN_REV_5000) { + if ((qman_version & QMAN_REV_MASK) >= QMAN_REV_5000 + && (d->cena_access_mode == qman_cena_fastest_access)) { p->eqcr.pi_ring_size = 32; qbman_swp_enqueue_array_mode_ptr = qbman_swp_enqueue_array_mode_mem_back; @@ -253,7 +255,8 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d) eqcr_pi = qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_EQCR_PI); p->eqcr.pi = eqcr_pi & p->eqcr.pi_mask; p->eqcr.pi_vb = eqcr_pi & QB_VALID_BIT; - if ((p->desc.qman_version & QMAN_REV_MASK) < QMAN_REV_5000) + if ((p->desc.qman_version & QMAN_REV_MASK) >= QMAN_REV_5000 + && (d->cena_access_mode == qman_cena_fastest_access)) p->eqcr.ci = qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_EQCR_CI) & p->eqcr.pi_mask; else @@ -362,10 +365,11 @@ void *qbman_swp_mc_start(struct qbman_swp *p) #ifdef QBMAN_CHECKING QBMAN_BUG_ON(p->mc.check != swp_mc_can_start); #endif - if ((p->desc.qman_version & QMAN_REV_MASK) < QMAN_REV_5000) - ret = qbman_cena_write_start(&p->sys, QBMAN_CENA_SWP_CR); - else + if ((p->desc.qman_version & QMAN_REV_MASK) >= QMAN_REV_5000 + && (p->desc.cena_access_mode == qman_cena_fastest_access)) ret = qbman_cena_write_start(&p->sys, QBMAN_CENA_SWP_CR_MEM); + else + ret = qbman_cena_write_start(&p->sys, QBMAN_CENA_SWP_CR); #ifdef QBMAN_CHECKING if (!ret) p->mc.check = swp_mc_can_submit; @@ -385,16 +389,17 @@ void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, uint8_t cmd_verb) * caller wants to OR but has forgotten to do so. */ QBMAN_BUG_ON((*v & cmd_verb) != *v); - if ((p->desc.qman_version & QMAN_REV_MASK) < QMAN_REV_5000) { - dma_wmb(); - *v = cmd_verb | p->mc.valid_bit; - qbman_cena_write_complete(&p->sys, QBMAN_CENA_SWP_CR, cmd); - clean(cmd); - } else { + if ((p->desc.qman_version & QMAN_REV_MASK) >= QMAN_REV_5000 + && (p->desc.cena_access_mode == qman_cena_fastest_access)) { *v = cmd_verb | p->mr.valid_bit; qbman_cena_write_complete(&p->sys, QBMAN_CENA_SWP_CR_MEM, cmd); dma_wmb(); qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_CR_RT, QMAN_RT_MODE); + } else { + dma_wmb(); + *v = cmd_verb | p->mc.valid_bit; + qbman_cena_write_complete(&p->sys, QBMAN_CENA_SWP_CR, cmd); + clean(cmd); } #ifdef QBMAN_CHECKING p->mc.check = swp_mc_can_poll; @@ -407,30 +412,31 @@ void *qbman_swp_mc_result(struct qbman_swp *p) #ifdef QBMAN_CHECKING QBMAN_BUG_ON(p->mc.check != swp_mc_can_poll); #endif - if ((p->desc.qman_version & QMAN_REV_MASK) < QMAN_REV_5000) { - qbman_cena_invalidate_prefetch(&p->sys, - QBMAN_CENA_SWP_RR(p->mc.valid_bit)); - ret = qbman_cena_read(&p->sys, - QBMAN_CENA_SWP_RR(p->mc.valid_bit)); + if ((p->desc.qman_version & QMAN_REV_MASK) >= QMAN_REV_5000 + && (p->desc.cena_access_mode == qman_cena_fastest_access)) { + ret = qbman_cena_read(&p->sys, QBMAN_CENA_SWP_RR_MEM); + /* Command completed if the valid bit is toggled */ + if (p->mr.valid_bit != (ret[0] & QB_VALID_BIT)) + return NULL; /* Remove the valid-bit - * command completed iff the rest is non-zero */ verb = ret[0] & ~QB_VALID_BIT; if (!verb) return NULL; - p->mc.valid_bit ^= QB_VALID_BIT; + p->mr.valid_bit ^= QB_VALID_BIT; } else { - ret = qbman_cena_read(&p->sys, QBMAN_CENA_SWP_RR_MEM); - /* Command completed if the valid bit is toggled */ - if (p->mr.valid_bit != (ret[0] & QB_VALID_BIT)) - return NULL; + qbman_cena_invalidate_prefetch(&p->sys, + QBMAN_CENA_SWP_RR(p->mc.valid_bit)); + ret = qbman_cena_read(&p->sys, + QBMAN_CENA_SWP_RR(p->mc.valid_bit)); /* Remove the valid-bit - * command completed iff the rest is non-zero */ verb = ret[0] & ~QB_VALID_BIT; if (!verb) return NULL; - p->mr.valid_bit ^= QB_VALID_BIT; + p->mc.valid_bit ^= QB_VALID_BIT; } #ifdef QBMAN_CHECKING p->mc.check = swp_mc_can_start; diff --git a/drivers/bus/fslmc/qbman/qbman_sys.h b/drivers/bus/fslmc/qbman/qbman_sys.h index e3bd1c5e64..71f7a67822 100644 --- a/drivers/bus/fslmc/qbman/qbman_sys.h +++ b/drivers/bus/fslmc/qbman/qbman_sys.h @@ -389,7 +389,8 @@ static inline int qbman_swp_sys_init(struct qbman_swp_sys *s, int i; int cena_region_size = 4*1024; - if ((d->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) + if ((d->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000 + && (d->cena_access_mode == qman_cena_fastest_access)) cena_region_size = 64*1024; #ifdef RTE_ARCH_64 uint8_t wn = CENA_WRITE_ENABLE; @@ -416,7 +417,8 @@ static inline int qbman_swp_sys_init(struct qbman_swp_sys *s, reg = qbman_cinh_read(s, QBMAN_CINH_SWP_CFG); QBMAN_BUG_ON(reg); #endif - if ((d->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) + if ((d->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000 + && (d->cena_access_mode == qman_cena_fastest_access)) memset(s->addr_cena, 0, cena_region_size); else { /* Invalidate the portal memory. @@ -426,11 +428,12 @@ static inline int qbman_swp_sys_init(struct qbman_swp_sys *s, dccivac(s->addr_cena + i); } - if (s->eqcr_mode == qman_eqcr_vb_array) + if (s->eqcr_mode == qman_eqcr_vb_array) { reg = qbman_set_swp_cfg(dqrr_size, wn, 0, 3, 2, 3, 1, 1, 1, 1, 1, 1); - else { - if ((d->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) + } else { + if ((d->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000 && + (d->cena_access_mode == qman_cena_fastest_access)) reg = qbman_set_swp_cfg(dqrr_size, wn, 1, 3, 2, 0, 1, 1, 1, 1, 1, 1); else @@ -438,11 +441,11 @@ static inline int qbman_swp_sys_init(struct qbman_swp_sys *s, 1, 3, 2, 2, 1, 1, 1, 1, 1, 1); } - if ((d->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) { + if ((d->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000 + && (d->cena_access_mode == qman_cena_fastest_access)) reg |= 1 << SWP_CFG_CPBS_SHIFT | /* memory-backed mode */ 1 << SWP_CFG_VPM_SHIFT | /* VDQCR read triggered mode */ 1 << SWP_CFG_CPM_SHIFT; /* CR read triggered mode */ - } qbman_cinh_write(s, QBMAN_CINH_SWP_CFG, reg); reg = qbman_cinh_read(s, QBMAN_CINH_SWP_CFG); @@ -452,7 +455,8 @@ static inline int qbman_swp_sys_init(struct qbman_swp_sys *s, return -1; } - if ((d->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) { + if ((d->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000 + && (d->cena_access_mode == qman_cena_fastest_access)) { qbman_cinh_write(s, QBMAN_CINH_SWP_EQCR_PI, QMAN_RT_MODE); qbman_cinh_write(s, QBMAN_CINH_SWP_RCR_PI, QMAN_RT_MODE); } -- 2.20.1