@@ -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) {
@@ -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 */
@@ -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;
@@ -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);
}