diff mbox series

[v3,10/19] bus/fslmc: add dynamic config for memback portal mode

Message ID 20190111122305.7133-11-shreyansh.jain@nxp.com
State New
Headers show
Series None | expand

Commit Message

Shreyansh Jain Jan. 11, 2019, 12:24 p.m. UTC
From: Hemant Agrawal <hemant.agrawal@nxp.com>


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      |  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(-)

-- 
2.17.1
diff mbox series

Patch

diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
index ba2e28ce1..37723a094 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 bb60a98f9..48bdaafa4 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 2f572a08b..08bfdc9f8 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 e3bd1c5e6..71f7a6782 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);
 	}