summaryrefslogtreecommitdiff
path: root/drivers/staging/fsl_qbman
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/fsl_qbman')
-rw-r--r--drivers/staging/fsl_qbman/fsl_usdpaa.c24
-rw-r--r--drivers/staging/fsl_qbman/qman_low.h19
2 files changed, 41 insertions, 2 deletions
diff --git a/drivers/staging/fsl_qbman/fsl_usdpaa.c b/drivers/staging/fsl_qbman/fsl_usdpaa.c
index 3a6d3722..ec5ea6e 100644
--- a/drivers/staging/fsl_qbman/fsl_usdpaa.c
+++ b/drivers/staging/fsl_qbman/fsl_usdpaa.c
@@ -371,6 +371,16 @@ static int usdpaa_open(struct inode *inode, struct file *filp)
#define DQRR_MAXFILL 15
+
+/* Invalidate a portal */
+void dbci_portal(void *addr)
+{
+ int i;
+
+ for (i = 0; i < 0x4000; i += 64)
+ dcbi(addr + i);
+}
+
/* Reset a QMan portal to its default state */
static int init_qm_portal(struct qm_portal_config *config,
struct qm_portal *portal)
@@ -384,6 +394,13 @@ static int init_qm_portal(struct qm_portal_config *config,
/* Make sure interrupts are inhibited */
qm_out(IIR, 1);
+ /*
+ * Invalidate the entire CE portal are to ensure no stale
+ * cachelines are present. This should be done on all
+ * cores as the portal is mapped as M=0 (non-coherent).
+ */
+ on_each_cpu(dbci_portal, portal->addr.addr_ce, 1);
+
/* Initialize the DQRR. This will stop any dequeue
commands that are in progress */
if (qm_dqrr_init(portal, config, qm_dqrr_dpush, qm_dqrr_pvb,
@@ -435,6 +452,13 @@ static int init_bm_portal(struct bm_portal_config *config,
portal->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
portal->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
+ /*
+ * Invalidate the entire CE portal are to ensure no stale
+ * cachelines are present. This should be done on all
+ * cores as the portal is mapped as M=0 (non-coherent).
+ */
+ on_each_cpu(dbci_portal, portal->addr.addr_ce, 1);
+
if (bm_rcr_init(portal, bm_rcr_pvb, bm_rcr_cce)) {
pr_err("Bman RCR initialisation failed\n");
return 1;
diff --git a/drivers/staging/fsl_qbman/qman_low.h b/drivers/staging/fsl_qbman/qman_low.h
index 547b5fa..e43f9ea 100644
--- a/drivers/staging/fsl_qbman/qman_low.h
+++ b/drivers/staging/fsl_qbman/qman_low.h
@@ -1095,11 +1095,26 @@ static inline void qm_mr_set_ithresh(struct qm_portal *portal, u8 ithresh)
static inline int qm_mc_init(struct qm_portal *portal)
{
+ u8 rr0, rr1;
register struct qm_mc *mc = &portal->mc;
+
mc->cr = portal->addr.addr_ce + QM_CL_CR;
mc->rr = portal->addr.addr_ce + QM_CL_RR0;
- mc->rridx = (__raw_readb(&mc->cr->__dont_write_directly__verb) &
- QM_MCC_VERB_VBIT) ? 0 : 1;
+
+ /*
+ * The expected valid bit polarity for the next CR command is 0
+ * if RR1 contains a valid response, and is 1 if RR0 contains a
+ * valid response. If both RR contain all 0, this indicates either
+ * that no command has been executed since reset (in which case the
+ * expected valid bit polarity is 1)
+ */
+ rr0 = __raw_readb(&mc->rr->verb);
+ rr1 = __raw_readb(&(mc->rr+1)->verb);
+ if ((rr0 == 0 && rr1 == 0) || rr0 != 0)
+ mc->rridx = 1;
+ else
+ mc->rridx = 0;
+
mc->vbit = mc->rridx ? QM_MCC_VERB_VBIT : 0;
#ifdef CONFIG_FSL_DPA_CHECKING
mc->state = qman_mc_idle;