/* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
*
*/
#ifndef _FSL_QBMAN_BASE_H
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 */
};
/**
* @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,
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 */
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);
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;
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
#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;
* 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;
#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;
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;
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.
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
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);
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);
}