bus/fslmc: add dynamic config for memback portal mode
authorHemant Agrawal <hemant.agrawal@nxp.com>
Fri, 11 Jan 2019 12:24:38 +0000 (12:24 +0000)
committerFerruh Yigit <ferruh.yigit@intel.com>
Mon, 14 Jan 2019 16:44:29 +0000 (17:44 +0100)
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 <roy.pledge@nxp.com>
Signed-off-by: Youri Querry <youri.querry_1@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
drivers/bus/fslmc/qbman/include/fsl_qbman_base.h
drivers/bus/fslmc/qbman/qbman_portal.c
drivers/bus/fslmc/qbman/qbman_sys.h

index ba2e28c..37723a0 100644 (file)
@@ -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) {
index bb60a98..48bdaaf 100644 (file)
@@ -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 */
index 2f572a0..08bfdc9 100644 (file)
@@ -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;
index e3bd1c5..71f7a67 100644 (file)
@@ -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);
        }