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