linux/drivers/soc/fsl/qbman/bman.c
<<
>>
Prefs
   1/* Copyright 2008 - 2016 Freescale Semiconductor, Inc.
   2 *
   3 * Redistribution and use in source and binary forms, with or without
   4 * modification, are permitted provided that the following conditions are met:
   5 *     * Redistributions of source code must retain the above copyright
   6 *       notice, this list of conditions and the following disclaimer.
   7 *     * Redistributions in binary form must reproduce the above copyright
   8 *       notice, this list of conditions and the following disclaimer in the
   9 *       documentation and/or other materials provided with the distribution.
  10 *     * Neither the name of Freescale Semiconductor nor the
  11 *       names of its contributors may be used to endorse or promote products
  12 *       derived from this software without specific prior written permission.
  13 *
  14 * ALTERNATIVELY, this software may be distributed under the terms of the
  15 * GNU General Public License ("GPL") as published by the Free Software
  16 * Foundation, either version 2 of that License or (at your option) any
  17 * later version.
  18 *
  19 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
  20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
  23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29 */
  30
  31#include "bman_priv.h"
  32
  33#define IRQNAME         "BMan portal %d"
  34#define MAX_IRQNAME     16      /* big enough for "BMan portal %d" */
  35
  36/* Portal register assists */
  37
  38#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
  39/* Cache-inhibited register offsets */
  40#define BM_REG_RCR_PI_CINH      0x3000
  41#define BM_REG_RCR_CI_CINH      0x3100
  42#define BM_REG_RCR_ITR          0x3200
  43#define BM_REG_CFG              0x3300
  44#define BM_REG_SCN(n)           (0x3400 + ((n) << 6))
  45#define BM_REG_ISR              0x3e00
  46#define BM_REG_IER              0x3e40
  47#define BM_REG_ISDR             0x3e80
  48#define BM_REG_IIR              0x3ec0
  49
  50/* Cache-enabled register offsets */
  51#define BM_CL_CR                0x0000
  52#define BM_CL_RR0               0x0100
  53#define BM_CL_RR1               0x0140
  54#define BM_CL_RCR               0x1000
  55#define BM_CL_RCR_PI_CENA       0x3000
  56#define BM_CL_RCR_CI_CENA       0x3100
  57
  58#else
  59/* Cache-inhibited register offsets */
  60#define BM_REG_RCR_PI_CINH      0x0000
  61#define BM_REG_RCR_CI_CINH      0x0004
  62#define BM_REG_RCR_ITR          0x0008
  63#define BM_REG_CFG              0x0100
  64#define BM_REG_SCN(n)           (0x0200 + ((n) << 2))
  65#define BM_REG_ISR              0x0e00
  66#define BM_REG_IER              0x0e04
  67#define BM_REG_ISDR             0x0e08
  68#define BM_REG_IIR              0x0e0c
  69
  70/* Cache-enabled register offsets */
  71#define BM_CL_CR                0x0000
  72#define BM_CL_RR0               0x0100
  73#define BM_CL_RR1               0x0140
  74#define BM_CL_RCR               0x1000
  75#define BM_CL_RCR_PI_CENA       0x3000
  76#define BM_CL_RCR_CI_CENA       0x3100
  77#endif
  78
  79/*
  80 * Portal modes.
  81 *   Enum types;
  82 *     pmode == production mode
  83 *     cmode == consumption mode,
  84 *   Enum values use 3 letter codes. First letter matches the portal mode,
  85 *   remaining two letters indicate;
  86 *     ci == cache-inhibited portal register
  87 *     ce == cache-enabled portal register
  88 *     vb == in-band valid-bit (cache-enabled)
  89 */
  90enum bm_rcr_pmode {             /* matches BCSP_CFG::RPM */
  91        bm_rcr_pci = 0,         /* PI index, cache-inhibited */
  92        bm_rcr_pce = 1,         /* PI index, cache-enabled */
  93        bm_rcr_pvb = 2          /* valid-bit */
  94};
  95enum bm_rcr_cmode {             /* s/w-only */
  96        bm_rcr_cci,             /* CI index, cache-inhibited */
  97        bm_rcr_cce              /* CI index, cache-enabled */
  98};
  99
 100
 101/* --- Portal structures --- */
 102
 103#define BM_RCR_SIZE             8
 104
 105/* Release Command */
 106struct bm_rcr_entry {
 107        union {
 108                struct {
 109                        u8 _ncw_verb; /* writes to this are non-coherent */
 110                        u8 bpid; /* used with BM_RCR_VERB_CMD_BPID_SINGLE */
 111                        u8 __reserved1[62];
 112                };
 113                struct bm_buffer bufs[8];
 114        };
 115};
 116#define BM_RCR_VERB_VBIT                0x80
 117#define BM_RCR_VERB_CMD_MASK            0x70    /* one of two values; */
 118#define BM_RCR_VERB_CMD_BPID_SINGLE     0x20
 119#define BM_RCR_VERB_CMD_BPID_MULTI      0x30
 120#define BM_RCR_VERB_BUFCOUNT_MASK       0x0f    /* values 1..8 */
 121
 122struct bm_rcr {
 123        struct bm_rcr_entry *ring, *cursor;
 124        u8 ci, available, ithresh, vbit;
 125#ifdef CONFIG_FSL_DPAA_CHECKING
 126        u32 busy;
 127        enum bm_rcr_pmode pmode;
 128        enum bm_rcr_cmode cmode;
 129#endif
 130};
 131
 132/* MC (Management Command) command */
 133struct bm_mc_command {
 134        u8 _ncw_verb; /* writes to this are non-coherent */
 135        u8 bpid; /* used by acquire command */
 136        u8 __reserved[62];
 137};
 138#define BM_MCC_VERB_VBIT                0x80
 139#define BM_MCC_VERB_CMD_MASK            0x70    /* where the verb contains; */
 140#define BM_MCC_VERB_CMD_ACQUIRE         0x10
 141#define BM_MCC_VERB_CMD_QUERY           0x40
 142#define BM_MCC_VERB_ACQUIRE_BUFCOUNT    0x0f    /* values 1..8 go here */
 143
 144/* MC result, Acquire and Query Response */
 145union bm_mc_result {
 146        struct {
 147                u8 verb;
 148                u8 bpid;
 149                u8 __reserved[62];
 150        };
 151        struct bm_buffer bufs[8];
 152};
 153#define BM_MCR_VERB_VBIT                0x80
 154#define BM_MCR_VERB_CMD_MASK            BM_MCC_VERB_CMD_MASK
 155#define BM_MCR_VERB_CMD_ACQUIRE         BM_MCC_VERB_CMD_ACQUIRE
 156#define BM_MCR_VERB_CMD_QUERY           BM_MCC_VERB_CMD_QUERY
 157#define BM_MCR_VERB_CMD_ERR_INVALID     0x60
 158#define BM_MCR_VERB_CMD_ERR_ECC         0x70
 159#define BM_MCR_VERB_ACQUIRE_BUFCOUNT    BM_MCC_VERB_ACQUIRE_BUFCOUNT /* 0..8 */
 160#define BM_MCR_TIMEOUT                  10000 /* us */
 161
 162struct bm_mc {
 163        struct bm_mc_command *cr;
 164        union bm_mc_result *rr;
 165        u8 rridx, vbit;
 166#ifdef CONFIG_FSL_DPAA_CHECKING
 167        enum {
 168                /* Can only be _mc_start()ed */
 169                mc_idle,
 170                /* Can only be _mc_commit()ed or _mc_abort()ed */
 171                mc_user,
 172                /* Can only be _mc_retry()ed */
 173                mc_hw
 174        } state;
 175#endif
 176};
 177
 178struct bm_addr {
 179        void *ce;               /* cache-enabled */
 180        __be32 *ce_be;          /* Same as above but for direct access */
 181        void __iomem *ci;       /* cache-inhibited */
 182};
 183
 184struct bm_portal {
 185        struct bm_addr addr;
 186        struct bm_rcr rcr;
 187        struct bm_mc mc;
 188} ____cacheline_aligned;
 189
 190/* Cache-inhibited register access. */
 191static inline u32 bm_in(struct bm_portal *p, u32 offset)
 192{
 193        return ioread32be(p->addr.ci + offset);
 194}
 195
 196static inline void bm_out(struct bm_portal *p, u32 offset, u32 val)
 197{
 198        iowrite32be(val, p->addr.ci + offset);
 199}
 200
 201/* Cache Enabled Portal Access */
 202static inline void bm_cl_invalidate(struct bm_portal *p, u32 offset)
 203{
 204        dpaa_invalidate(p->addr.ce + offset);
 205}
 206
 207static inline void bm_cl_touch_ro(struct bm_portal *p, u32 offset)
 208{
 209        dpaa_touch_ro(p->addr.ce + offset);
 210}
 211
 212static inline u32 bm_ce_in(struct bm_portal *p, u32 offset)
 213{
 214        return be32_to_cpu(*(p->addr.ce_be + (offset/4)));
 215}
 216
 217struct bman_portal {
 218        struct bm_portal p;
 219        /* interrupt sources processed by portal_isr(), configurable */
 220        unsigned long irq_sources;
 221        /* probing time config params for cpu-affine portals */
 222        const struct bm_portal_config *config;
 223        char irqname[MAX_IRQNAME];
 224};
 225
 226static cpumask_t affine_mask;
 227static DEFINE_SPINLOCK(affine_mask_lock);
 228static DEFINE_PER_CPU(struct bman_portal, bman_affine_portal);
 229
 230static inline struct bman_portal *get_affine_portal(void)
 231{
 232        return &get_cpu_var(bman_affine_portal);
 233}
 234
 235static inline void put_affine_portal(void)
 236{
 237        put_cpu_var(bman_affine_portal);
 238}
 239
 240/*
 241 * This object type refers to a pool, it isn't *the* pool. There may be
 242 * more than one such object per BMan buffer pool, eg. if different users of the
 243 * pool are operating via different portals.
 244 */
 245struct bman_pool {
 246        /* index of the buffer pool to encapsulate (0-63) */
 247        u32 bpid;
 248        /* Used for hash-table admin when using depletion notifications. */
 249        struct bman_portal *portal;
 250        struct bman_pool *next;
 251};
 252
 253static u32 poll_portal_slow(struct bman_portal *p, u32 is);
 254
 255static irqreturn_t portal_isr(int irq, void *ptr)
 256{
 257        struct bman_portal *p = ptr;
 258        struct bm_portal *portal = &p->p;
 259        u32 clear = p->irq_sources;
 260        u32 is = bm_in(portal, BM_REG_ISR) & p->irq_sources;
 261
 262        if (unlikely(!is))
 263                return IRQ_NONE;
 264
 265        clear |= poll_portal_slow(p, is);
 266        bm_out(portal, BM_REG_ISR, clear);
 267        return IRQ_HANDLED;
 268}
 269
 270/* --- RCR API --- */
 271
 272#define RCR_SHIFT       ilog2(sizeof(struct bm_rcr_entry))
 273#define RCR_CARRY       (uintptr_t)(BM_RCR_SIZE << RCR_SHIFT)
 274
 275/* Bit-wise logic to wrap a ring pointer by clearing the "carry bit" */
 276static struct bm_rcr_entry *rcr_carryclear(struct bm_rcr_entry *p)
 277{
 278        uintptr_t addr = (uintptr_t)p;
 279
 280        addr &= ~RCR_CARRY;
 281
 282        return (struct bm_rcr_entry *)addr;
 283}
 284
 285#ifdef CONFIG_FSL_DPAA_CHECKING
 286/* Bit-wise logic to convert a ring pointer to a ring index */
 287static int rcr_ptr2idx(struct bm_rcr_entry *e)
 288{
 289        return ((uintptr_t)e >> RCR_SHIFT) & (BM_RCR_SIZE - 1);
 290}
 291#endif
 292
 293/* Increment the 'cursor' ring pointer, taking 'vbit' into account */
 294static inline void rcr_inc(struct bm_rcr *rcr)
 295{
 296        /* increment to the next RCR pointer and handle overflow and 'vbit' */
 297        struct bm_rcr_entry *partial = rcr->cursor + 1;
 298
 299        rcr->cursor = rcr_carryclear(partial);
 300        if (partial != rcr->cursor)
 301                rcr->vbit ^= BM_RCR_VERB_VBIT;
 302}
 303
 304static int bm_rcr_get_avail(struct bm_portal *portal)
 305{
 306        struct bm_rcr *rcr = &portal->rcr;
 307
 308        return rcr->available;
 309}
 310
 311static int bm_rcr_get_fill(struct bm_portal *portal)
 312{
 313        struct bm_rcr *rcr = &portal->rcr;
 314
 315        return BM_RCR_SIZE - 1 - rcr->available;
 316}
 317
 318static void bm_rcr_set_ithresh(struct bm_portal *portal, u8 ithresh)
 319{
 320        struct bm_rcr *rcr = &portal->rcr;
 321
 322        rcr->ithresh = ithresh;
 323        bm_out(portal, BM_REG_RCR_ITR, ithresh);
 324}
 325
 326static void bm_rcr_cce_prefetch(struct bm_portal *portal)
 327{
 328        __maybe_unused struct bm_rcr *rcr = &portal->rcr;
 329
 330        DPAA_ASSERT(rcr->cmode == bm_rcr_cce);
 331        bm_cl_touch_ro(portal, BM_CL_RCR_CI_CENA);
 332}
 333
 334static u8 bm_rcr_cce_update(struct bm_portal *portal)
 335{
 336        struct bm_rcr *rcr = &portal->rcr;
 337        u8 diff, old_ci = rcr->ci;
 338
 339        DPAA_ASSERT(rcr->cmode == bm_rcr_cce);
 340        rcr->ci = bm_ce_in(portal, BM_CL_RCR_CI_CENA) & (BM_RCR_SIZE - 1);
 341        bm_cl_invalidate(portal, BM_CL_RCR_CI_CENA);
 342        diff = dpaa_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci);
 343        rcr->available += diff;
 344        return diff;
 345}
 346
 347static inline struct bm_rcr_entry *bm_rcr_start(struct bm_portal *portal)
 348{
 349        struct bm_rcr *rcr = &portal->rcr;
 350
 351        DPAA_ASSERT(!rcr->busy);
 352        if (!rcr->available)
 353                return NULL;
 354#ifdef CONFIG_FSL_DPAA_CHECKING
 355        rcr->busy = 1;
 356#endif
 357        dpaa_zero(rcr->cursor);
 358        return rcr->cursor;
 359}
 360
 361static inline void bm_rcr_pvb_commit(struct bm_portal *portal, u8 myverb)
 362{
 363        struct bm_rcr *rcr = &portal->rcr;
 364        struct bm_rcr_entry *rcursor;
 365
 366        DPAA_ASSERT(rcr->busy);
 367        DPAA_ASSERT(rcr->pmode == bm_rcr_pvb);
 368        DPAA_ASSERT(rcr->available >= 1);
 369        dma_wmb();
 370        rcursor = rcr->cursor;
 371        rcursor->_ncw_verb = myverb | rcr->vbit;
 372        dpaa_flush(rcursor);
 373        rcr_inc(rcr);
 374        rcr->available--;
 375#ifdef CONFIG_FSL_DPAA_CHECKING
 376        rcr->busy = 0;
 377#endif
 378}
 379
 380static int bm_rcr_init(struct bm_portal *portal, enum bm_rcr_pmode pmode,
 381                       enum bm_rcr_cmode cmode)
 382{
 383        struct bm_rcr *rcr = &portal->rcr;
 384        u32 cfg;
 385        u8 pi;
 386
 387        rcr->ring = portal->addr.ce + BM_CL_RCR;
 388        rcr->ci = bm_in(portal, BM_REG_RCR_CI_CINH) & (BM_RCR_SIZE - 1);
 389        pi = bm_in(portal, BM_REG_RCR_PI_CINH) & (BM_RCR_SIZE - 1);
 390        rcr->cursor = rcr->ring + pi;
 391        rcr->vbit = (bm_in(portal, BM_REG_RCR_PI_CINH) & BM_RCR_SIZE) ?
 392                BM_RCR_VERB_VBIT : 0;
 393        rcr->available = BM_RCR_SIZE - 1
 394                - dpaa_cyc_diff(BM_RCR_SIZE, rcr->ci, pi);
 395        rcr->ithresh = bm_in(portal, BM_REG_RCR_ITR);
 396#ifdef CONFIG_FSL_DPAA_CHECKING
 397        rcr->busy = 0;
 398        rcr->pmode = pmode;
 399        rcr->cmode = cmode;
 400#endif
 401        cfg = (bm_in(portal, BM_REG_CFG) & 0xffffffe0)
 402                | (pmode & 0x3); /* BCSP_CFG::RPM */
 403        bm_out(portal, BM_REG_CFG, cfg);
 404        return 0;
 405}
 406
 407static void bm_rcr_finish(struct bm_portal *portal)
 408{
 409#ifdef CONFIG_FSL_DPAA_CHECKING
 410        struct bm_rcr *rcr = &portal->rcr;
 411        int i;
 412
 413        DPAA_ASSERT(!rcr->busy);
 414
 415        i = bm_in(portal, BM_REG_RCR_PI_CINH) & (BM_RCR_SIZE - 1);
 416        if (i != rcr_ptr2idx(rcr->cursor))
 417                pr_crit("losing uncommitted RCR entries\n");
 418
 419        i = bm_in(portal, BM_REG_RCR_CI_CINH) & (BM_RCR_SIZE - 1);
 420        if (i != rcr->ci)
 421                pr_crit("missing existing RCR completions\n");
 422        if (rcr->ci != rcr_ptr2idx(rcr->cursor))
 423                pr_crit("RCR destroyed unquiesced\n");
 424#endif
 425}
 426
 427/* --- Management command API --- */
 428static int bm_mc_init(struct bm_portal *portal)
 429{
 430        struct bm_mc *mc = &portal->mc;
 431
 432        mc->cr = portal->addr.ce + BM_CL_CR;
 433        mc->rr = portal->addr.ce + BM_CL_RR0;
 434        mc->rridx = (mc->cr->_ncw_verb & BM_MCC_VERB_VBIT) ?
 435                    0 : 1;
 436        mc->vbit = mc->rridx ? BM_MCC_VERB_VBIT : 0;
 437#ifdef CONFIG_FSL_DPAA_CHECKING
 438        mc->state = mc_idle;
 439#endif
 440        return 0;
 441}
 442
 443static void bm_mc_finish(struct bm_portal *portal)
 444{
 445#ifdef CONFIG_FSL_DPAA_CHECKING
 446        struct bm_mc *mc = &portal->mc;
 447
 448        DPAA_ASSERT(mc->state == mc_idle);
 449        if (mc->state != mc_idle)
 450                pr_crit("Losing incomplete MC command\n");
 451#endif
 452}
 453
 454static inline struct bm_mc_command *bm_mc_start(struct bm_portal *portal)
 455{
 456        struct bm_mc *mc = &portal->mc;
 457
 458        DPAA_ASSERT(mc->state == mc_idle);
 459#ifdef CONFIG_FSL_DPAA_CHECKING
 460        mc->state = mc_user;
 461#endif
 462        dpaa_zero(mc->cr);
 463        return mc->cr;
 464}
 465
 466static inline void bm_mc_commit(struct bm_portal *portal, u8 myverb)
 467{
 468        struct bm_mc *mc = &portal->mc;
 469        union bm_mc_result *rr = mc->rr + mc->rridx;
 470
 471        DPAA_ASSERT(mc->state == mc_user);
 472        dma_wmb();
 473        mc->cr->_ncw_verb = myverb | mc->vbit;
 474        dpaa_flush(mc->cr);
 475        dpaa_invalidate_touch_ro(rr);
 476#ifdef CONFIG_FSL_DPAA_CHECKING
 477        mc->state = mc_hw;
 478#endif
 479}
 480
 481static inline union bm_mc_result *bm_mc_result(struct bm_portal *portal)
 482{
 483        struct bm_mc *mc = &portal->mc;
 484        union bm_mc_result *rr = mc->rr + mc->rridx;
 485
 486        DPAA_ASSERT(mc->state == mc_hw);
 487        /*
 488         * The inactive response register's verb byte always returns zero until
 489         * its command is submitted and completed. This includes the valid-bit,
 490         * in case you were wondering...
 491         */
 492        if (!rr->verb) {
 493                dpaa_invalidate_touch_ro(rr);
 494                return NULL;
 495        }
 496        mc->rridx ^= 1;
 497        mc->vbit ^= BM_MCC_VERB_VBIT;
 498#ifdef CONFIG_FSL_DPAA_CHECKING
 499        mc->state = mc_idle;
 500#endif
 501        return rr;
 502}
 503
 504static inline int bm_mc_result_timeout(struct bm_portal *portal,
 505                                       union bm_mc_result **mcr)
 506{
 507        int timeout = BM_MCR_TIMEOUT;
 508
 509        do {
 510                *mcr = bm_mc_result(portal);
 511                if (*mcr)
 512                        break;
 513                udelay(1);
 514        } while (--timeout);
 515
 516        return timeout;
 517}
 518
 519/* Disable all BSCN interrupts for the portal */
 520static void bm_isr_bscn_disable(struct bm_portal *portal)
 521{
 522        bm_out(portal, BM_REG_SCN(0), 0);
 523        bm_out(portal, BM_REG_SCN(1), 0);
 524}
 525
 526static int bman_create_portal(struct bman_portal *portal,
 527                              const struct bm_portal_config *c)
 528{
 529        struct bm_portal *p;
 530        int ret;
 531
 532        p = &portal->p;
 533        /*
 534         * prep the low-level portal struct with the mapped addresses from the
 535         * config, everything that follows depends on it and "config" is more
 536         * for (de)reference...
 537         */
 538        p->addr.ce = c->addr_virt_ce;
 539        p->addr.ce_be = c->addr_virt_ce;
 540        p->addr.ci = c->addr_virt_ci;
 541        if (bm_rcr_init(p, bm_rcr_pvb, bm_rcr_cce)) {
 542                dev_err(c->dev, "RCR initialisation failed\n");
 543                goto fail_rcr;
 544        }
 545        if (bm_mc_init(p)) {
 546                dev_err(c->dev, "MC initialisation failed\n");
 547                goto fail_mc;
 548        }
 549        /*
 550         * Default to all BPIDs disabled, we enable as required at
 551         * run-time.
 552         */
 553        bm_isr_bscn_disable(p);
 554
 555        /* Write-to-clear any stale interrupt status bits */
 556        bm_out(p, BM_REG_ISDR, 0xffffffff);
 557        portal->irq_sources = 0;
 558        bm_out(p, BM_REG_IER, 0);
 559        bm_out(p, BM_REG_ISR, 0xffffffff);
 560        snprintf(portal->irqname, MAX_IRQNAME, IRQNAME, c->cpu);
 561        if (request_irq(c->irq, portal_isr, 0, portal->irqname, portal)) {
 562                dev_err(c->dev, "request_irq() failed\n");
 563                goto fail_irq;
 564        }
 565
 566        if (dpaa_set_portal_irq_affinity(c->dev, c->irq, c->cpu))
 567                goto fail_affinity;
 568
 569        /* Need RCR to be empty before continuing */
 570        ret = bm_rcr_get_fill(p);
 571        if (ret) {
 572                dev_err(c->dev, "RCR unclean\n");
 573                goto fail_rcr_empty;
 574        }
 575        /* Success */
 576        portal->config = c;
 577
 578        bm_out(p, BM_REG_ISDR, 0);
 579        bm_out(p, BM_REG_IIR, 0);
 580
 581        return 0;
 582
 583fail_rcr_empty:
 584fail_affinity:
 585        free_irq(c->irq, portal);
 586fail_irq:
 587        bm_mc_finish(p);
 588fail_mc:
 589        bm_rcr_finish(p);
 590fail_rcr:
 591        return -EIO;
 592}
 593
 594struct bman_portal *bman_create_affine_portal(const struct bm_portal_config *c)
 595{
 596        struct bman_portal *portal;
 597        int err;
 598
 599        portal = &per_cpu(bman_affine_portal, c->cpu);
 600        err = bman_create_portal(portal, c);
 601        if (err)
 602                return NULL;
 603
 604        spin_lock(&affine_mask_lock);
 605        cpumask_set_cpu(c->cpu, &affine_mask);
 606        spin_unlock(&affine_mask_lock);
 607
 608        return portal;
 609}
 610
 611static u32 poll_portal_slow(struct bman_portal *p, u32 is)
 612{
 613        u32 ret = is;
 614
 615        if (is & BM_PIRQ_RCRI) {
 616                bm_rcr_cce_update(&p->p);
 617                bm_rcr_set_ithresh(&p->p, 0);
 618                bm_out(&p->p, BM_REG_ISR, BM_PIRQ_RCRI);
 619                is &= ~BM_PIRQ_RCRI;
 620        }
 621
 622        /* There should be no status register bits left undefined */
 623        DPAA_ASSERT(!is);
 624        return ret;
 625}
 626
 627int bman_p_irqsource_add(struct bman_portal *p, u32 bits)
 628{
 629        unsigned long irqflags;
 630
 631        local_irq_save(irqflags);
 632        p->irq_sources |= bits & BM_PIRQ_VISIBLE;
 633        bm_out(&p->p, BM_REG_IER, p->irq_sources);
 634        local_irq_restore(irqflags);
 635        return 0;
 636}
 637
 638int bm_shutdown_pool(u32 bpid)
 639{
 640        int err = 0;
 641        struct bm_mc_command *bm_cmd;
 642        union bm_mc_result *bm_res;
 643
 644
 645        struct bman_portal *p = get_affine_portal();
 646        while (1) {
 647                /* Acquire buffers until empty */
 648                bm_cmd = bm_mc_start(&p->p);
 649                bm_cmd->bpid = bpid;
 650                bm_mc_commit(&p->p, BM_MCC_VERB_CMD_ACQUIRE | 1);
 651                if (!bm_mc_result_timeout(&p->p, &bm_res)) {
 652                        pr_crit("BMan Acquire Command timedout\n");
 653                        err = -ETIMEDOUT;
 654                        goto done;
 655                }
 656                if (!(bm_res->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT)) {
 657                        /* Pool is empty */
 658                        goto done;
 659                }
 660        }
 661done:
 662        put_affine_portal();
 663        return err;
 664}
 665
 666struct gen_pool *bm_bpalloc;
 667
 668static int bm_alloc_bpid_range(u32 *result, u32 count)
 669{
 670        unsigned long addr;
 671
 672        addr = gen_pool_alloc(bm_bpalloc, count);
 673        if (!addr)
 674                return -ENOMEM;
 675
 676        *result = addr & ~DPAA_GENALLOC_OFF;
 677
 678        return 0;
 679}
 680
 681static int bm_release_bpid(u32 bpid)
 682{
 683        int ret;
 684
 685        ret = bm_shutdown_pool(bpid);
 686        if (ret) {
 687                pr_debug("BPID %d leaked\n", bpid);
 688                return ret;
 689        }
 690
 691        gen_pool_free(bm_bpalloc, bpid | DPAA_GENALLOC_OFF, 1);
 692        return 0;
 693}
 694
 695struct bman_pool *bman_new_pool(void)
 696{
 697        struct bman_pool *pool = NULL;
 698        u32 bpid;
 699
 700        if (bm_alloc_bpid_range(&bpid, 1))
 701                return NULL;
 702
 703        pool = kmalloc(sizeof(*pool), GFP_KERNEL);
 704        if (!pool)
 705                goto err;
 706
 707        pool->bpid = bpid;
 708
 709        return pool;
 710err:
 711        bm_release_bpid(bpid);
 712        return NULL;
 713}
 714EXPORT_SYMBOL(bman_new_pool);
 715
 716void bman_free_pool(struct bman_pool *pool)
 717{
 718        bm_release_bpid(pool->bpid);
 719
 720        kfree(pool);
 721}
 722EXPORT_SYMBOL(bman_free_pool);
 723
 724int bman_get_bpid(const struct bman_pool *pool)
 725{
 726        return pool->bpid;
 727}
 728EXPORT_SYMBOL(bman_get_bpid);
 729
 730static void update_rcr_ci(struct bman_portal *p, int avail)
 731{
 732        if (avail)
 733                bm_rcr_cce_prefetch(&p->p);
 734        else
 735                bm_rcr_cce_update(&p->p);
 736}
 737
 738int bman_release(struct bman_pool *pool, const struct bm_buffer *bufs, u8 num)
 739{
 740        struct bman_portal *p;
 741        struct bm_rcr_entry *r;
 742        unsigned long irqflags;
 743        int avail, timeout = 1000; /* 1ms */
 744        int i = num - 1;
 745
 746        DPAA_ASSERT(num > 0 && num <= 8);
 747
 748        do {
 749                p = get_affine_portal();
 750                local_irq_save(irqflags);
 751                avail = bm_rcr_get_avail(&p->p);
 752                if (avail < 2)
 753                        update_rcr_ci(p, avail);
 754                r = bm_rcr_start(&p->p);
 755                local_irq_restore(irqflags);
 756                put_affine_portal();
 757                if (likely(r))
 758                        break;
 759
 760                udelay(1);
 761        } while (--timeout);
 762
 763        if (unlikely(!timeout))
 764                return -ETIMEDOUT;
 765
 766        p = get_affine_portal();
 767        local_irq_save(irqflags);
 768        /*
 769         * we can copy all but the first entry, as this can trigger badness
 770         * with the valid-bit
 771         */
 772        bm_buffer_set64(r->bufs, bm_buffer_get64(bufs));
 773        bm_buffer_set_bpid(r->bufs, pool->bpid);
 774        if (i)
 775                memcpy(&r->bufs[1], &bufs[1], i * sizeof(bufs[0]));
 776
 777        bm_rcr_pvb_commit(&p->p, BM_RCR_VERB_CMD_BPID_SINGLE |
 778                          (num & BM_RCR_VERB_BUFCOUNT_MASK));
 779
 780        local_irq_restore(irqflags);
 781        put_affine_portal();
 782        return 0;
 783}
 784EXPORT_SYMBOL(bman_release);
 785
 786int bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, u8 num)
 787{
 788        struct bman_portal *p = get_affine_portal();
 789        struct bm_mc_command *mcc;
 790        union bm_mc_result *mcr;
 791        int ret;
 792
 793        DPAA_ASSERT(num > 0 && num <= 8);
 794
 795        mcc = bm_mc_start(&p->p);
 796        mcc->bpid = pool->bpid;
 797        bm_mc_commit(&p->p, BM_MCC_VERB_CMD_ACQUIRE |
 798                     (num & BM_MCC_VERB_ACQUIRE_BUFCOUNT));
 799        if (!bm_mc_result_timeout(&p->p, &mcr)) {
 800                put_affine_portal();
 801                pr_crit("BMan Acquire Timeout\n");
 802                return -ETIMEDOUT;
 803        }
 804        ret = mcr->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT;
 805        if (bufs)
 806                memcpy(&bufs[0], &mcr->bufs[0], num * sizeof(bufs[0]));
 807
 808        put_affine_portal();
 809        if (ret != num)
 810                ret = -ENOMEM;
 811        return ret;
 812}
 813EXPORT_SYMBOL(bman_acquire);
 814
 815const struct bm_portal_config *
 816bman_get_bm_portal_config(const struct bman_portal *portal)
 817{
 818        return portal->config;
 819}
 820