t_Error bm_rcr_init(struct bm_portal *portal, e_BmPortalProduceMode pmode, e_BmPortalRcrConsumeMode cmode) { register struct bm_rcr *rcr = &portal->rcr; uint32_t cfg; uint8_t pi; rcr->ring = ptr_ADD(portal->addr.addr_ce, CL_RCR); rcr->ci = (uint8_t)(bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1)); pi = (uint8_t)(bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1)); rcr->cursor = rcr->ring + pi; rcr->vbit = (uint8_t)((bm_in(RCR_PI_CINH) & BM_RCR_SIZE) ? BM_RCR_VERB_VBIT : 0); rcr->available = (uint8_t)(BM_RCR_SIZE - 1 - cyc_diff(BM_RCR_SIZE, rcr->ci, pi)); rcr->ithresh = (uint8_t)bm_in(RCR_ITR); #ifdef BM_CHECKING rcr->busy = 0; rcr->pmode = pmode; rcr->cmode = cmode; #else UNUSED(cmode); #endif /* BM_CHECKING */ cfg = (bm_in(CFG) & 0xffffffe0) | (pmode & 0x3); /* BCSP_CFG::RPM */ bm_out(CFG, cfg); return 0; }
static int bm_rcr_init(struct bm_portal *portal, enum bm_rcr_pmode pmode, enum bm_rcr_cmode cmode) { struct bm_rcr *rcr = &portal->rcr; u32 cfg; u8 pi; rcr->ring = portal->addr.ce + BM_CL_RCR; rcr->ci = bm_in(portal, BM_REG_RCR_CI_CINH) & (BM_RCR_SIZE - 1); pi = bm_in(portal, BM_REG_RCR_PI_CINH) & (BM_RCR_SIZE - 1); rcr->cursor = rcr->ring + pi; rcr->vbit = (bm_in(portal, BM_REG_RCR_PI_CINH) & BM_RCR_SIZE) ? BM_RCR_VERB_VBIT : 0; rcr->available = BM_RCR_SIZE - 1 - dpaa_cyc_diff(BM_RCR_SIZE, rcr->ci, pi); rcr->ithresh = bm_in(portal, BM_REG_RCR_ITR); #ifdef CONFIG_FSL_DPAA_CHECKING rcr->busy = 0; rcr->pmode = pmode; rcr->cmode = cmode; #endif cfg = (bm_in(portal, BM_REG_CFG) & 0xffffffe0) | (pmode & 0x3); /* BCSP_CFG::RPM */ bm_out(portal, BM_REG_CFG, cfg); return 0; }
static void bm_rcr_set_ithresh(struct bm_portal *portal, u8 ithresh) { struct bm_rcr *rcr = &portal->rcr; rcr->ithresh = ithresh; bm_out(portal, BM_REG_RCR_ITR, ithresh); }
int bman_p_irqsource_add(struct bman_portal *p, u32 bits) { unsigned long irqflags; local_irq_save(irqflags); set_bits(bits & BM_PIRQ_VISIBLE, &p->irq_sources); bm_out(&p->p, BM_REG_IER, p->irq_sources); local_irq_restore(irqflags); return 0; }
void bm_rcr_pci_commit(struct bm_portal *portal, uint8_t myverb) { register struct bm_rcr *rcr = &portal->rcr; ASSERT_COND(rcr->busy); ASSERT_COND(rcr->pmode == e_BmPortalPCI); rcr->cursor->__dont_write_directly__verb = (uint8_t)(myverb | rcr->vbit); RCR_INC(rcr); rcr->available--; hwsync(); bm_out(RCR_PI_CINH, RCR_PTR2IDX(rcr->cursor)); #ifdef BM_CHECKING rcr->busy = 0; #endif /* BM_CHECKING */ }
static irqreturn_t portal_isr(int irq, void *ptr) { struct bman_portal *p = ptr; struct bm_portal *portal = &p->p; u32 clear = p->irq_sources; u32 is = bm_in(portal, BM_REG_ISR) & p->irq_sources; if (unlikely(!is)) return IRQ_NONE; clear |= poll_portal_slow(p, is); bm_out(portal, BM_REG_ISR, clear); return IRQ_HANDLED; }
static u32 poll_portal_slow(struct bman_portal *p, u32 is) { u32 ret = is; if (is & BM_PIRQ_RCRI) { bm_rcr_cce_update(&p->p); bm_rcr_set_ithresh(&p->p, 0); bm_out(&p->p, BM_REG_ISR, BM_PIRQ_RCRI); is &= ~BM_PIRQ_RCRI; } /* There should be no status register bits left undefined */ DPAA_ASSERT(!is); return ret; }
void bm_rcr_set_ithresh(struct bm_portal *portal, uint8_t ithresh) { register struct bm_rcr *rcr = &portal->rcr; rcr->ithresh = ithresh; bm_out(RCR_ITR, ithresh); }
static int bman_create_portal(struct bman_portal *portal, const struct bm_portal_config *c) { struct bm_portal *p; int ret; p = &portal->p; /* * prep the low-level portal struct with the mapped addresses from the * config, everything that follows depends on it and "config" is more * for (de)reference... */ p->addr.ce = c->addr_virt[DPAA_PORTAL_CE]; p->addr.ci = c->addr_virt[DPAA_PORTAL_CI]; if (bm_rcr_init(p, bm_rcr_pvb, bm_rcr_cce)) { dev_err(c->dev, "RCR initialisation failed\n"); goto fail_rcr; } if (bm_mc_init(p)) { dev_err(c->dev, "MC initialisation failed\n"); goto fail_mc; } /* * Default to all BPIDs disabled, we enable as required at * run-time. */ bm_isr_bscn_disable(p); /* Write-to-clear any stale interrupt status bits */ bm_out(p, BM_REG_ISDR, 0xffffffff); portal->irq_sources = 0; bm_out(p, BM_REG_IER, 0); bm_out(p, BM_REG_ISR, 0xffffffff); snprintf(portal->irqname, MAX_IRQNAME, IRQNAME, c->cpu); if (request_irq(c->irq, portal_isr, 0, portal->irqname, portal)) { dev_err(c->dev, "request_irq() failed\n"); goto fail_irq; } if (c->cpu != -1 && irq_can_set_affinity(c->irq) && irq_set_affinity(c->irq, cpumask_of(c->cpu))) { dev_err(c->dev, "irq_set_affinity() failed\n"); goto fail_affinity; } /* Need RCR to be empty before continuing */ ret = bm_rcr_get_fill(p); if (ret) { dev_err(c->dev, "RCR unclean\n"); goto fail_rcr_empty; } /* Success */ portal->config = c; bm_out(p, BM_REG_ISDR, 0); bm_out(p, BM_REG_IIR, 0); return 0; fail_rcr_empty: fail_affinity: free_irq(c->irq, portal); fail_irq: bm_mc_finish(p); fail_mc: bm_rcr_finish(p); fail_rcr: return -EIO; }
/* Disable all BSCN interrupts for the portal */ static void bm_isr_bscn_disable(struct bm_portal *portal) { bm_out(portal, BM_REG_SCN(0), 0); bm_out(portal, BM_REG_SCN(1), 0); }