1d81734caSHemant Agrawal /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2f38f61e9SShreyansh Jain *
3f38f61e9SShreyansh Jain * Copyright 2010-2016 Freescale Semiconductor Inc.
4d81734caSHemant Agrawal * Copyright 2017 NXP
5f38f61e9SShreyansh Jain *
6f38f61e9SShreyansh Jain */
7f38f61e9SShreyansh Jain
8f38f61e9SShreyansh Jain #ifndef __BMAN_H
9f38f61e9SShreyansh Jain #define __BMAN_H
10f38f61e9SShreyansh Jain
11f38f61e9SShreyansh Jain #include "bman_priv.h"
12f38f61e9SShreyansh Jain
13f38f61e9SShreyansh Jain /* Cache-inhibited register offsets */
14f38f61e9SShreyansh Jain #define BM_REG_RCR_PI_CINH 0x3000
15f38f61e9SShreyansh Jain #define BM_REG_RCR_CI_CINH 0x3100
16f38f61e9SShreyansh Jain #define BM_REG_RCR_ITR 0x3200
17f38f61e9SShreyansh Jain #define BM_REG_CFG 0x3300
18f38f61e9SShreyansh Jain #define BM_REG_SCN(n) (0x3400 + ((n) << 6))
19f38f61e9SShreyansh Jain #define BM_REG_ISR 0x3e00
20f38f61e9SShreyansh Jain #define BM_REG_IIR 0x3ec0
21f38f61e9SShreyansh Jain
22f38f61e9SShreyansh Jain /* Cache-enabled register offsets */
23f38f61e9SShreyansh Jain #define BM_CL_CR 0x0000
24f38f61e9SShreyansh Jain #define BM_CL_RR0 0x0100
25f38f61e9SShreyansh Jain #define BM_CL_RR1 0x0140
26f38f61e9SShreyansh Jain #define BM_CL_RCR 0x1000
27f38f61e9SShreyansh Jain #define BM_CL_RCR_PI_CENA 0x3000
28f38f61e9SShreyansh Jain #define BM_CL_RCR_CI_CENA 0x3100
29f38f61e9SShreyansh Jain
30f38f61e9SShreyansh Jain /* BTW, the drivers (and h/w programming model) already obtain the required
31f38f61e9SShreyansh Jain * synchronisation for portal accesses via lwsync(), hwsync(), and
32f38f61e9SShreyansh Jain * data-dependencies. Use of barrier()s or other order-preserving primitives
33f38f61e9SShreyansh Jain * simply degrade performance. Hence the use of the __raw_*() interfaces, which
34f38f61e9SShreyansh Jain * simply ensure that the compiler treats the portal registers as volatile (ie.
35f38f61e9SShreyansh Jain * non-coherent).
36f38f61e9SShreyansh Jain */
37f38f61e9SShreyansh Jain
38f38f61e9SShreyansh Jain /* Cache-inhibited register access. */
39f38f61e9SShreyansh Jain #define __bm_in(bm, o) be32_to_cpu(__raw_readl((bm)->ci + (o)))
40f38f61e9SShreyansh Jain #define __bm_out(bm, o, val) __raw_writel(cpu_to_be32(val), \
41f38f61e9SShreyansh Jain (bm)->ci + (o))
42f38f61e9SShreyansh Jain #define bm_in(reg) __bm_in(&portal->addr, BM_REG_##reg)
43f38f61e9SShreyansh Jain #define bm_out(reg, val) __bm_out(&portal->addr, BM_REG_##reg, val)
44f38f61e9SShreyansh Jain
45f38f61e9SShreyansh Jain /* Cache-enabled (index) register access */
46f38f61e9SShreyansh Jain #define __bm_cl_touch_ro(bm, o) dcbt_ro((bm)->ce + (o))
47f38f61e9SShreyansh Jain #define __bm_cl_touch_rw(bm, o) dcbt_rw((bm)->ce + (o))
48f38f61e9SShreyansh Jain #define __bm_cl_in(bm, o) be32_to_cpu(__raw_readl((bm)->ce + (o)))
49f38f61e9SShreyansh Jain #define __bm_cl_out(bm, o, val) \
50f38f61e9SShreyansh Jain do { \
51f38f61e9SShreyansh Jain u32 *__tmpclout = (bm)->ce + (o); \
52f38f61e9SShreyansh Jain __raw_writel(cpu_to_be32(val), __tmpclout); \
53f38f61e9SShreyansh Jain dcbf(__tmpclout); \
54f38f61e9SShreyansh Jain } while (0)
55f38f61e9SShreyansh Jain #define __bm_cl_invalidate(bm, o) dccivac((bm)->ce + (o))
56f38f61e9SShreyansh Jain #define bm_cl_touch_ro(reg) __bm_cl_touch_ro(&portal->addr, BM_CL_##reg##_CENA)
57f38f61e9SShreyansh Jain #define bm_cl_touch_rw(reg) __bm_cl_touch_rw(&portal->addr, BM_CL_##reg##_CENA)
58f38f61e9SShreyansh Jain #define bm_cl_in(reg) __bm_cl_in(&portal->addr, BM_CL_##reg##_CENA)
59f38f61e9SShreyansh Jain #define bm_cl_out(reg, val) __bm_cl_out(&portal->addr, BM_CL_##reg##_CENA, val)
60f38f61e9SShreyansh Jain #define bm_cl_invalidate(reg)\
61f38f61e9SShreyansh Jain __bm_cl_invalidate(&portal->addr, BM_CL_##reg##_CENA)
62f38f61e9SShreyansh Jain
63f38f61e9SShreyansh Jain /* Cyclic helper for rings. FIXME: once we are able to do fine-grain perf
64f38f61e9SShreyansh Jain * analysis, look at using the "extra" bit in the ring index registers to avoid
65f38f61e9SShreyansh Jain * cyclic issues.
66f38f61e9SShreyansh Jain */
bm_cyc_diff(u8 ringsize,u8 first,u8 last)67f38f61e9SShreyansh Jain static inline u8 bm_cyc_diff(u8 ringsize, u8 first, u8 last)
68f38f61e9SShreyansh Jain {
69f38f61e9SShreyansh Jain /* 'first' is included, 'last' is excluded */
70f38f61e9SShreyansh Jain if (first <= last)
71f38f61e9SShreyansh Jain return last - first;
72f38f61e9SShreyansh Jain return ringsize + last - first;
73f38f61e9SShreyansh Jain }
74f38f61e9SShreyansh Jain
75f38f61e9SShreyansh Jain /* Portal modes.
76f38f61e9SShreyansh Jain * Enum types;
77f38f61e9SShreyansh Jain * pmode == production mode
78f38f61e9SShreyansh Jain * cmode == consumption mode,
79f38f61e9SShreyansh Jain * Enum values use 3 letter codes. First letter matches the portal mode,
80f38f61e9SShreyansh Jain * remaining two letters indicate;
81f38f61e9SShreyansh Jain * ci == cache-inhibited portal register
82f38f61e9SShreyansh Jain * ce == cache-enabled portal register
83f38f61e9SShreyansh Jain * vb == in-band valid-bit (cache-enabled)
84f38f61e9SShreyansh Jain */
85f38f61e9SShreyansh Jain enum bm_rcr_pmode { /* matches BCSP_CFG::RPM */
86f38f61e9SShreyansh Jain bm_rcr_pci = 0, /* PI index, cache-inhibited */
87f38f61e9SShreyansh Jain bm_rcr_pce = 1, /* PI index, cache-enabled */
88f38f61e9SShreyansh Jain bm_rcr_pvb = 2 /* valid-bit */
89f38f61e9SShreyansh Jain };
90f38f61e9SShreyansh Jain
91f38f61e9SShreyansh Jain enum bm_rcr_cmode { /* s/w-only */
92f38f61e9SShreyansh Jain bm_rcr_cci, /* CI index, cache-inhibited */
93f38f61e9SShreyansh Jain bm_rcr_cce /* CI index, cache-enabled */
94f38f61e9SShreyansh Jain };
95f38f61e9SShreyansh Jain
96f38f61e9SShreyansh Jain /* --- Portal structures --- */
97f38f61e9SShreyansh Jain
98f38f61e9SShreyansh Jain #define BM_RCR_SIZE 8
99f38f61e9SShreyansh Jain
100f38f61e9SShreyansh Jain struct bm_rcr {
101f38f61e9SShreyansh Jain struct bm_rcr_entry *ring, *cursor;
102f38f61e9SShreyansh Jain u8 ci, available, ithresh, vbit;
103f38f61e9SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
104f38f61e9SShreyansh Jain u32 busy;
105f38f61e9SShreyansh Jain enum bm_rcr_pmode pmode;
106f38f61e9SShreyansh Jain enum bm_rcr_cmode cmode;
107f38f61e9SShreyansh Jain #endif
108f38f61e9SShreyansh Jain };
109f38f61e9SShreyansh Jain
110f38f61e9SShreyansh Jain struct bm_mc {
111f38f61e9SShreyansh Jain struct bm_mc_command *cr;
112f38f61e9SShreyansh Jain struct bm_mc_result *rr;
113f38f61e9SShreyansh Jain u8 rridx, vbit;
114f38f61e9SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
115f38f61e9SShreyansh Jain enum {
116f38f61e9SShreyansh Jain /* Can only be _mc_start()ed */
117f38f61e9SShreyansh Jain mc_idle,
118f38f61e9SShreyansh Jain /* Can only be _mc_commit()ed or _mc_abort()ed */
119f38f61e9SShreyansh Jain mc_user,
120f38f61e9SShreyansh Jain /* Can only be _mc_retry()ed */
121f38f61e9SShreyansh Jain mc_hw
122f38f61e9SShreyansh Jain } state;
123f38f61e9SShreyansh Jain #endif
124f38f61e9SShreyansh Jain };
125f38f61e9SShreyansh Jain
126f38f61e9SShreyansh Jain struct bm_addr {
127f38f61e9SShreyansh Jain void __iomem *ce; /* cache-enabled */
128f38f61e9SShreyansh Jain void __iomem *ci; /* cache-inhibited */
129f38f61e9SShreyansh Jain };
130f38f61e9SShreyansh Jain
131f38f61e9SShreyansh Jain struct bm_portal {
132f38f61e9SShreyansh Jain struct bm_addr addr;
133f38f61e9SShreyansh Jain struct bm_rcr rcr;
134f38f61e9SShreyansh Jain struct bm_mc mc;
135f38f61e9SShreyansh Jain struct bm_portal_config config;
136f38f61e9SShreyansh Jain } ____cacheline_aligned;
137f38f61e9SShreyansh Jain
138f38f61e9SShreyansh Jain /* Bit-wise logic to wrap a ring pointer by clearing the "carry bit" */
139f38f61e9SShreyansh Jain #define RCR_CARRYCLEAR(p) \
140f38f61e9SShreyansh Jain (void *)((unsigned long)(p) & (~(unsigned long)(BM_RCR_SIZE << 6)))
141f38f61e9SShreyansh Jain
142f38f61e9SShreyansh Jain /* Bit-wise logic to convert a ring pointer to a ring index */
RCR_PTR2IDX(struct bm_rcr_entry * e)143f38f61e9SShreyansh Jain static inline u8 RCR_PTR2IDX(struct bm_rcr_entry *e)
144f38f61e9SShreyansh Jain {
145f38f61e9SShreyansh Jain return ((uintptr_t)e >> 6) & (BM_RCR_SIZE - 1);
146f38f61e9SShreyansh Jain }
147f38f61e9SShreyansh Jain
148f38f61e9SShreyansh Jain /* Increment the 'cursor' ring pointer, taking 'vbit' into account */
RCR_INC(struct bm_rcr * rcr)149f38f61e9SShreyansh Jain static inline void RCR_INC(struct bm_rcr *rcr)
150f38f61e9SShreyansh Jain {
151f38f61e9SShreyansh Jain /* NB: this is odd-looking, but experiments show that it generates
152f38f61e9SShreyansh Jain * fast code with essentially no branching overheads. We increment to
153f38f61e9SShreyansh Jain * the next RCR pointer and handle overflow and 'vbit'.
154f38f61e9SShreyansh Jain */
155f38f61e9SShreyansh Jain struct bm_rcr_entry *partial = rcr->cursor + 1;
156f38f61e9SShreyansh Jain
157f38f61e9SShreyansh Jain rcr->cursor = RCR_CARRYCLEAR(partial);
158f38f61e9SShreyansh Jain if (partial != rcr->cursor)
159f38f61e9SShreyansh Jain rcr->vbit ^= BM_RCR_VERB_VBIT;
160f38f61e9SShreyansh Jain }
161f38f61e9SShreyansh Jain
bm_rcr_init(struct bm_portal * portal,enum bm_rcr_pmode pmode,__maybe_unused enum bm_rcr_cmode cmode)162f38f61e9SShreyansh Jain static inline int bm_rcr_init(struct bm_portal *portal, enum bm_rcr_pmode pmode,
163f38f61e9SShreyansh Jain __maybe_unused enum bm_rcr_cmode cmode)
164f38f61e9SShreyansh Jain {
165f38f61e9SShreyansh Jain /* This use of 'register', as well as all other occurrences, is because
166f38f61e9SShreyansh Jain * it has been observed to generate much faster code with gcc than is
167f38f61e9SShreyansh Jain * otherwise the case.
168f38f61e9SShreyansh Jain */
169f38f61e9SShreyansh Jain register struct bm_rcr *rcr = &portal->rcr;
170f38f61e9SShreyansh Jain u32 cfg;
171f38f61e9SShreyansh Jain u8 pi;
172f38f61e9SShreyansh Jain
173f38f61e9SShreyansh Jain rcr->ring = portal->addr.ce + BM_CL_RCR;
174f38f61e9SShreyansh Jain rcr->ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
175f38f61e9SShreyansh Jain
176f38f61e9SShreyansh Jain pi = bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1);
177f38f61e9SShreyansh Jain rcr->cursor = rcr->ring + pi;
178f38f61e9SShreyansh Jain rcr->vbit = (bm_in(RCR_PI_CINH) & BM_RCR_SIZE) ? BM_RCR_VERB_VBIT : 0;
179f38f61e9SShreyansh Jain rcr->available = BM_RCR_SIZE - 1
180f38f61e9SShreyansh Jain - bm_cyc_diff(BM_RCR_SIZE, rcr->ci, pi);
181f38f61e9SShreyansh Jain rcr->ithresh = bm_in(RCR_ITR);
182f38f61e9SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
183f38f61e9SShreyansh Jain rcr->busy = 0;
184f38f61e9SShreyansh Jain rcr->pmode = pmode;
185f38f61e9SShreyansh Jain rcr->cmode = cmode;
186f38f61e9SShreyansh Jain #endif
187f38f61e9SShreyansh Jain cfg = (bm_in(CFG) & 0xffffffe0) | (pmode & 0x3); /* BCSP_CFG::RPM */
188f38f61e9SShreyansh Jain bm_out(CFG, cfg);
189f38f61e9SShreyansh Jain return 0;
190f38f61e9SShreyansh Jain }
191f38f61e9SShreyansh Jain
bm_rcr_finish(struct bm_portal * portal)192f38f61e9SShreyansh Jain static inline void bm_rcr_finish(struct bm_portal *portal)
193f38f61e9SShreyansh Jain {
194f38f61e9SShreyansh Jain register struct bm_rcr *rcr = &portal->rcr;
195f38f61e9SShreyansh Jain u8 pi = bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1);
196f38f61e9SShreyansh Jain u8 ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
197f38f61e9SShreyansh Jain
198996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
199f38f61e9SShreyansh Jain DPAA_ASSERT(!rcr->busy);
200996672d3SFerruh Yigit #endif
201f38f61e9SShreyansh Jain if (pi != RCR_PTR2IDX(rcr->cursor))
202f38f61e9SShreyansh Jain pr_crit("losing uncommitted RCR entries\n");
203f38f61e9SShreyansh Jain if (ci != rcr->ci)
204f38f61e9SShreyansh Jain pr_crit("missing existing RCR completions\n");
205f38f61e9SShreyansh Jain if (rcr->ci != RCR_PTR2IDX(rcr->cursor))
206f38f61e9SShreyansh Jain pr_crit("RCR destroyed unquiesced\n");
207f38f61e9SShreyansh Jain }
208f38f61e9SShreyansh Jain
bm_rcr_start(struct bm_portal * portal)209f38f61e9SShreyansh Jain static inline struct bm_rcr_entry *bm_rcr_start(struct bm_portal *portal)
210f38f61e9SShreyansh Jain {
211f38f61e9SShreyansh Jain register struct bm_rcr *rcr = &portal->rcr;
212f38f61e9SShreyansh Jain
213996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
214f38f61e9SShreyansh Jain DPAA_ASSERT(!rcr->busy);
215996672d3SFerruh Yigit #endif
216f38f61e9SShreyansh Jain if (!rcr->available)
217f38f61e9SShreyansh Jain return NULL;
218f38f61e9SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
219f38f61e9SShreyansh Jain rcr->busy = 1;
220f38f61e9SShreyansh Jain #endif
221f38f61e9SShreyansh Jain dcbz_64(rcr->cursor);
222f38f61e9SShreyansh Jain return rcr->cursor;
223f38f61e9SShreyansh Jain }
224f38f61e9SShreyansh Jain
bm_rcr_abort(struct bm_portal * portal)225f38f61e9SShreyansh Jain static inline void bm_rcr_abort(struct bm_portal *portal)
226f38f61e9SShreyansh Jain {
227f38f61e9SShreyansh Jain __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
228f38f61e9SShreyansh Jain
229f38f61e9SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
230996672d3SFerruh Yigit DPAA_ASSERT(rcr->busy);
231f38f61e9SShreyansh Jain rcr->busy = 0;
232f38f61e9SShreyansh Jain #endif
233f38f61e9SShreyansh Jain }
234f38f61e9SShreyansh Jain
bm_rcr_pend_and_next(struct bm_portal * portal,u8 myverb)235f38f61e9SShreyansh Jain static inline struct bm_rcr_entry *bm_rcr_pend_and_next(
236f38f61e9SShreyansh Jain struct bm_portal *portal, u8 myverb)
237f38f61e9SShreyansh Jain {
238f38f61e9SShreyansh Jain register struct bm_rcr *rcr = &portal->rcr;
239f38f61e9SShreyansh Jain
240996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
241f38f61e9SShreyansh Jain DPAA_ASSERT(rcr->busy);
242f38f61e9SShreyansh Jain DPAA_ASSERT(rcr->pmode != bm_rcr_pvb);
243996672d3SFerruh Yigit #endif
244f38f61e9SShreyansh Jain if (rcr->available == 1)
245f38f61e9SShreyansh Jain return NULL;
246f38f61e9SShreyansh Jain rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
247f38f61e9SShreyansh Jain dcbf_64(rcr->cursor);
248f38f61e9SShreyansh Jain RCR_INC(rcr);
249f38f61e9SShreyansh Jain rcr->available--;
250f38f61e9SShreyansh Jain dcbz_64(rcr->cursor);
251f38f61e9SShreyansh Jain return rcr->cursor;
252f38f61e9SShreyansh Jain }
253f38f61e9SShreyansh Jain
bm_rcr_pci_commit(struct bm_portal * portal,u8 myverb)254f38f61e9SShreyansh Jain static inline void bm_rcr_pci_commit(struct bm_portal *portal, u8 myverb)
255f38f61e9SShreyansh Jain {
256f38f61e9SShreyansh Jain register struct bm_rcr *rcr = &portal->rcr;
257f38f61e9SShreyansh Jain
258996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
259f38f61e9SShreyansh Jain DPAA_ASSERT(rcr->busy);
260f38f61e9SShreyansh Jain DPAA_ASSERT(rcr->pmode == bm_rcr_pci);
261996672d3SFerruh Yigit #endif
262f38f61e9SShreyansh Jain rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
263f38f61e9SShreyansh Jain RCR_INC(rcr);
264f38f61e9SShreyansh Jain rcr->available--;
265f38f61e9SShreyansh Jain hwsync();
266f38f61e9SShreyansh Jain bm_out(RCR_PI_CINH, RCR_PTR2IDX(rcr->cursor));
267f38f61e9SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
268f38f61e9SShreyansh Jain rcr->busy = 0;
269f38f61e9SShreyansh Jain #endif
270f38f61e9SShreyansh Jain }
271f38f61e9SShreyansh Jain
bm_rcr_pce_prefetch(struct bm_portal * portal)272f38f61e9SShreyansh Jain static inline void bm_rcr_pce_prefetch(struct bm_portal *portal)
273f38f61e9SShreyansh Jain {
274f38f61e9SShreyansh Jain __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
275f38f61e9SShreyansh Jain
276996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
277f38f61e9SShreyansh Jain DPAA_ASSERT(rcr->pmode == bm_rcr_pce);
278996672d3SFerruh Yigit #endif
279f38f61e9SShreyansh Jain bm_cl_invalidate(RCR_PI);
280f38f61e9SShreyansh Jain bm_cl_touch_rw(RCR_PI);
281f38f61e9SShreyansh Jain }
282f38f61e9SShreyansh Jain
bm_rcr_pce_commit(struct bm_portal * portal,u8 myverb)283f38f61e9SShreyansh Jain static inline void bm_rcr_pce_commit(struct bm_portal *portal, u8 myverb)
284f38f61e9SShreyansh Jain {
285f38f61e9SShreyansh Jain register struct bm_rcr *rcr = &portal->rcr;
286f38f61e9SShreyansh Jain
287996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
288f38f61e9SShreyansh Jain DPAA_ASSERT(rcr->busy);
289f38f61e9SShreyansh Jain DPAA_ASSERT(rcr->pmode == bm_rcr_pce);
290996672d3SFerruh Yigit #endif
291f38f61e9SShreyansh Jain rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
292f38f61e9SShreyansh Jain RCR_INC(rcr);
293f38f61e9SShreyansh Jain rcr->available--;
294f38f61e9SShreyansh Jain lwsync();
295f38f61e9SShreyansh Jain bm_cl_out(RCR_PI, RCR_PTR2IDX(rcr->cursor));
296f38f61e9SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
297f38f61e9SShreyansh Jain rcr->busy = 0;
298f38f61e9SShreyansh Jain #endif
299f38f61e9SShreyansh Jain }
300f38f61e9SShreyansh Jain
bm_rcr_pvb_commit(struct bm_portal * portal,u8 myverb)301f38f61e9SShreyansh Jain static inline void bm_rcr_pvb_commit(struct bm_portal *portal, u8 myverb)
302f38f61e9SShreyansh Jain {
303f38f61e9SShreyansh Jain register struct bm_rcr *rcr = &portal->rcr;
304f38f61e9SShreyansh Jain struct bm_rcr_entry *rcursor;
305f38f61e9SShreyansh Jain
306996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
307f38f61e9SShreyansh Jain DPAA_ASSERT(rcr->busy);
308f38f61e9SShreyansh Jain DPAA_ASSERT(rcr->pmode == bm_rcr_pvb);
309996672d3SFerruh Yigit #endif
310f38f61e9SShreyansh Jain lwsync();
311f38f61e9SShreyansh Jain rcursor = rcr->cursor;
312f38f61e9SShreyansh Jain rcursor->__dont_write_directly__verb = myverb | rcr->vbit;
313f38f61e9SShreyansh Jain dcbf_64(rcursor);
314f38f61e9SShreyansh Jain RCR_INC(rcr);
315f38f61e9SShreyansh Jain rcr->available--;
316f38f61e9SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
317f38f61e9SShreyansh Jain rcr->busy = 0;
318f38f61e9SShreyansh Jain #endif
319f38f61e9SShreyansh Jain }
320f38f61e9SShreyansh Jain
bm_rcr_cci_update(struct bm_portal * portal)321f38f61e9SShreyansh Jain static inline u8 bm_rcr_cci_update(struct bm_portal *portal)
322f38f61e9SShreyansh Jain {
323f38f61e9SShreyansh Jain register struct bm_rcr *rcr = &portal->rcr;
324f38f61e9SShreyansh Jain u8 diff, old_ci = rcr->ci;
325f38f61e9SShreyansh Jain
326996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
327f38f61e9SShreyansh Jain DPAA_ASSERT(rcr->cmode == bm_rcr_cci);
328996672d3SFerruh Yigit #endif
329f38f61e9SShreyansh Jain rcr->ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
330f38f61e9SShreyansh Jain diff = bm_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci);
331f38f61e9SShreyansh Jain rcr->available += diff;
332f38f61e9SShreyansh Jain return diff;
333f38f61e9SShreyansh Jain }
334f38f61e9SShreyansh Jain
bm_rcr_cce_prefetch(struct bm_portal * portal)335f38f61e9SShreyansh Jain static inline void bm_rcr_cce_prefetch(struct bm_portal *portal)
336f38f61e9SShreyansh Jain {
337f38f61e9SShreyansh Jain __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
338f38f61e9SShreyansh Jain
339996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
340f38f61e9SShreyansh Jain DPAA_ASSERT(rcr->cmode == bm_rcr_cce);
341996672d3SFerruh Yigit #endif
342f38f61e9SShreyansh Jain bm_cl_touch_ro(RCR_CI);
343f38f61e9SShreyansh Jain }
344f38f61e9SShreyansh Jain
bm_rcr_cce_update(struct bm_portal * portal)345f38f61e9SShreyansh Jain static inline u8 bm_rcr_cce_update(struct bm_portal *portal)
346f38f61e9SShreyansh Jain {
347f38f61e9SShreyansh Jain register struct bm_rcr *rcr = &portal->rcr;
348f38f61e9SShreyansh Jain u8 diff, old_ci = rcr->ci;
349f38f61e9SShreyansh Jain
350996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
351f38f61e9SShreyansh Jain DPAA_ASSERT(rcr->cmode == bm_rcr_cce);
352996672d3SFerruh Yigit #endif
353f38f61e9SShreyansh Jain rcr->ci = bm_cl_in(RCR_CI) & (BM_RCR_SIZE - 1);
354f38f61e9SShreyansh Jain bm_cl_invalidate(RCR_CI);
355f38f61e9SShreyansh Jain diff = bm_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci);
356f38f61e9SShreyansh Jain rcr->available += diff;
357f38f61e9SShreyansh Jain return diff;
358f38f61e9SShreyansh Jain }
359f38f61e9SShreyansh Jain
bm_rcr_get_ithresh(struct bm_portal * portal)360f38f61e9SShreyansh Jain static inline u8 bm_rcr_get_ithresh(struct bm_portal *portal)
361f38f61e9SShreyansh Jain {
362f38f61e9SShreyansh Jain register struct bm_rcr *rcr = &portal->rcr;
363f38f61e9SShreyansh Jain
364f38f61e9SShreyansh Jain return rcr->ithresh;
365f38f61e9SShreyansh Jain }
366f38f61e9SShreyansh Jain
bm_rcr_set_ithresh(struct bm_portal * portal,u8 ithresh)367f38f61e9SShreyansh Jain static inline void bm_rcr_set_ithresh(struct bm_portal *portal, u8 ithresh)
368f38f61e9SShreyansh Jain {
369f38f61e9SShreyansh Jain register struct bm_rcr *rcr = &portal->rcr;
370f38f61e9SShreyansh Jain
371f38f61e9SShreyansh Jain rcr->ithresh = ithresh;
372f38f61e9SShreyansh Jain bm_out(RCR_ITR, ithresh);
373f38f61e9SShreyansh Jain }
374f38f61e9SShreyansh Jain
bm_rcr_get_avail(struct bm_portal * portal)375f38f61e9SShreyansh Jain static inline u8 bm_rcr_get_avail(struct bm_portal *portal)
376f38f61e9SShreyansh Jain {
377f38f61e9SShreyansh Jain register struct bm_rcr *rcr = &portal->rcr;
378f38f61e9SShreyansh Jain
379f38f61e9SShreyansh Jain return rcr->available;
380f38f61e9SShreyansh Jain }
381f38f61e9SShreyansh Jain
bm_rcr_get_fill(struct bm_portal * portal)382f38f61e9SShreyansh Jain static inline u8 bm_rcr_get_fill(struct bm_portal *portal)
383f38f61e9SShreyansh Jain {
384f38f61e9SShreyansh Jain register struct bm_rcr *rcr = &portal->rcr;
385f38f61e9SShreyansh Jain
386f38f61e9SShreyansh Jain return BM_RCR_SIZE - 1 - rcr->available;
387f38f61e9SShreyansh Jain }
388f38f61e9SShreyansh Jain
389f38f61e9SShreyansh Jain /* --- Management command API --- */
390f38f61e9SShreyansh Jain
bm_mc_init(struct bm_portal * portal)391f38f61e9SShreyansh Jain static inline int bm_mc_init(struct bm_portal *portal)
392f38f61e9SShreyansh Jain {
393f38f61e9SShreyansh Jain register struct bm_mc *mc = &portal->mc;
394f38f61e9SShreyansh Jain
395f38f61e9SShreyansh Jain mc->cr = portal->addr.ce + BM_CL_CR;
396f38f61e9SShreyansh Jain mc->rr = portal->addr.ce + BM_CL_RR0;
397f38f61e9SShreyansh Jain mc->rridx = (__raw_readb(&mc->cr->__dont_write_directly__verb) &
398f38f61e9SShreyansh Jain BM_MCC_VERB_VBIT) ? 0 : 1;
399f38f61e9SShreyansh Jain mc->vbit = mc->rridx ? BM_MCC_VERB_VBIT : 0;
400f38f61e9SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
401f38f61e9SShreyansh Jain mc->state = mc_idle;
402f38f61e9SShreyansh Jain #endif
403f38f61e9SShreyansh Jain return 0;
404f38f61e9SShreyansh Jain }
405f38f61e9SShreyansh Jain
bm_mc_finish(struct bm_portal * portal)406f38f61e9SShreyansh Jain static inline void bm_mc_finish(struct bm_portal *portal)
407f38f61e9SShreyansh Jain {
408f38f61e9SShreyansh Jain __maybe_unused register struct bm_mc *mc = &portal->mc;
409f38f61e9SShreyansh Jain
410f38f61e9SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
411996672d3SFerruh Yigit DPAA_ASSERT(mc->state == mc_idle);
412f38f61e9SShreyansh Jain if (mc->state != mc_idle)
413f38f61e9SShreyansh Jain pr_crit("Losing incomplete MC command\n");
414f38f61e9SShreyansh Jain #endif
415f38f61e9SShreyansh Jain }
416f38f61e9SShreyansh Jain
bm_mc_start(struct bm_portal * portal)417f38f61e9SShreyansh Jain static inline struct bm_mc_command *bm_mc_start(struct bm_portal *portal)
418f38f61e9SShreyansh Jain {
419f38f61e9SShreyansh Jain register struct bm_mc *mc = &portal->mc;
420f38f61e9SShreyansh Jain
421f38f61e9SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
422996672d3SFerruh Yigit DPAA_ASSERT(mc->state == mc_idle);
423f38f61e9SShreyansh Jain mc->state = mc_user;
424f38f61e9SShreyansh Jain #endif
425f38f61e9SShreyansh Jain dcbz_64(mc->cr);
426f38f61e9SShreyansh Jain return mc->cr;
427f38f61e9SShreyansh Jain }
428f38f61e9SShreyansh Jain
bm_mc_abort(struct bm_portal * portal)429f38f61e9SShreyansh Jain static inline void bm_mc_abort(struct bm_portal *portal)
430f38f61e9SShreyansh Jain {
431f38f61e9SShreyansh Jain __maybe_unused register struct bm_mc *mc = &portal->mc;
432f38f61e9SShreyansh Jain
433f38f61e9SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
434996672d3SFerruh Yigit DPAA_ASSERT(mc->state == mc_user);
435f38f61e9SShreyansh Jain mc->state = mc_idle;
436f38f61e9SShreyansh Jain #endif
437f38f61e9SShreyansh Jain }
438f38f61e9SShreyansh Jain
bm_mc_commit(struct bm_portal * portal,u8 myverb)439f38f61e9SShreyansh Jain static inline void bm_mc_commit(struct bm_portal *portal, u8 myverb)
440f38f61e9SShreyansh Jain {
441f38f61e9SShreyansh Jain register struct bm_mc *mc = &portal->mc;
442f38f61e9SShreyansh Jain struct bm_mc_result *rr = mc->rr + mc->rridx;
443f38f61e9SShreyansh Jain
444996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
445f38f61e9SShreyansh Jain DPAA_ASSERT(mc->state == mc_user);
446996672d3SFerruh Yigit #endif
447f38f61e9SShreyansh Jain lwsync();
448f38f61e9SShreyansh Jain mc->cr->__dont_write_directly__verb = myverb | mc->vbit;
449f38f61e9SShreyansh Jain dcbf(mc->cr);
450f38f61e9SShreyansh Jain dcbit_ro(rr);
451f38f61e9SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
452f38f61e9SShreyansh Jain mc->state = mc_hw;
453f38f61e9SShreyansh Jain #endif
454f38f61e9SShreyansh Jain }
455f38f61e9SShreyansh Jain
bm_mc_result(struct bm_portal * portal)456f38f61e9SShreyansh Jain static inline struct bm_mc_result *bm_mc_result(struct bm_portal *portal)
457f38f61e9SShreyansh Jain {
458f38f61e9SShreyansh Jain register struct bm_mc *mc = &portal->mc;
459f38f61e9SShreyansh Jain struct bm_mc_result *rr = mc->rr + mc->rridx;
460f38f61e9SShreyansh Jain
461996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
462f38f61e9SShreyansh Jain DPAA_ASSERT(mc->state == mc_hw);
463996672d3SFerruh Yigit #endif
464f38f61e9SShreyansh Jain /* The inactive response register's verb byte always returns zero until
465f38f61e9SShreyansh Jain * its command is submitted and completed. This includes the valid-bit,
466f38f61e9SShreyansh Jain * in case you were wondering.
467f38f61e9SShreyansh Jain */
468f38f61e9SShreyansh Jain if (!__raw_readb(&rr->verb)) {
469f38f61e9SShreyansh Jain dcbit_ro(rr);
470f38f61e9SShreyansh Jain return NULL;
471f38f61e9SShreyansh Jain }
472f38f61e9SShreyansh Jain mc->rridx ^= 1;
473f38f61e9SShreyansh Jain mc->vbit ^= BM_MCC_VERB_VBIT;
474f38f61e9SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
475f38f61e9SShreyansh Jain mc->state = mc_idle;
476f38f61e9SShreyansh Jain #endif
477f38f61e9SShreyansh Jain return rr;
478f38f61e9SShreyansh Jain }
479f38f61e9SShreyansh Jain
480f38f61e9SShreyansh Jain #define SCN_REG(bpid) BM_REG_SCN((bpid) / 32)
481f38f61e9SShreyansh Jain #define SCN_BIT(bpid) (0x80000000 >> (bpid & 31))
bm_isr_bscn_mask(struct bm_portal * portal,u8 bpid,int enable)482f38f61e9SShreyansh Jain static inline void bm_isr_bscn_mask(struct bm_portal *portal, u8 bpid,
483f38f61e9SShreyansh Jain int enable)
484f38f61e9SShreyansh Jain {
485f38f61e9SShreyansh Jain u32 val;
486f38f61e9SShreyansh Jain
487f38f61e9SShreyansh Jain DPAA_ASSERT(bpid < bman_pool_max);
488f38f61e9SShreyansh Jain /* REG_SCN for bpid=0..31, REG_SCN+4 for bpid=32..63 */
489f38f61e9SShreyansh Jain val = __bm_in(&portal->addr, SCN_REG(bpid));
490f38f61e9SShreyansh Jain if (enable)
491f38f61e9SShreyansh Jain val |= SCN_BIT(bpid);
492f38f61e9SShreyansh Jain else
493f38f61e9SShreyansh Jain val &= ~SCN_BIT(bpid);
494f38f61e9SShreyansh Jain __bm_out(&portal->addr, SCN_REG(bpid), val);
495f38f61e9SShreyansh Jain }
496f38f61e9SShreyansh Jain
__bm_isr_read(struct bm_portal * portal,enum bm_isr_reg n)497f38f61e9SShreyansh Jain static inline u32 __bm_isr_read(struct bm_portal *portal, enum bm_isr_reg n)
498f38f61e9SShreyansh Jain {
499f38f61e9SShreyansh Jain #if defined(RTE_ARCH_ARM64)
500f38f61e9SShreyansh Jain return __bm_in(&portal->addr, BM_REG_ISR + (n << 6));
501f38f61e9SShreyansh Jain #else
502f38f61e9SShreyansh Jain return __bm_in(&portal->addr, BM_REG_ISR + (n << 2));
503f38f61e9SShreyansh Jain #endif
504f38f61e9SShreyansh Jain }
505f38f61e9SShreyansh Jain
__bm_isr_write(struct bm_portal * portal,enum bm_isr_reg n,u32 val)506f38f61e9SShreyansh Jain static inline void __bm_isr_write(struct bm_portal *portal, enum bm_isr_reg n,
507f38f61e9SShreyansh Jain u32 val)
508f38f61e9SShreyansh Jain {
509f38f61e9SShreyansh Jain #if defined(RTE_ARCH_ARM64)
510f38f61e9SShreyansh Jain __bm_out(&portal->addr, BM_REG_ISR + (n << 6), val);
511f38f61e9SShreyansh Jain #else
512f38f61e9SShreyansh Jain __bm_out(&portal->addr, BM_REG_ISR + (n << 2), val);
513f38f61e9SShreyansh Jain #endif
514f38f61e9SShreyansh Jain }
515f38f61e9SShreyansh Jain
516f38f61e9SShreyansh Jain /* Buffer Pool Cleanup */
bm_shutdown_pool(struct bm_portal * p,u32 bpid)517f38f61e9SShreyansh Jain static inline int bm_shutdown_pool(struct bm_portal *p, u32 bpid)
518f38f61e9SShreyansh Jain {
519f38f61e9SShreyansh Jain struct bm_mc_command *bm_cmd;
520f38f61e9SShreyansh Jain struct bm_mc_result *bm_res;
521f38f61e9SShreyansh Jain
522f38f61e9SShreyansh Jain bool stop = false;
523f38f61e9SShreyansh Jain
524f38f61e9SShreyansh Jain while (!stop) {
525f38f61e9SShreyansh Jain /* Acquire buffers until empty */
526f38f61e9SShreyansh Jain bm_cmd = bm_mc_start(p);
527f38f61e9SShreyansh Jain bm_cmd->acquire.bpid = bpid;
528f38f61e9SShreyansh Jain bm_mc_commit(p, BM_MCC_VERB_CMD_ACQUIRE | 1);
529f38f61e9SShreyansh Jain while (!(bm_res = bm_mc_result(p)))
530f38f61e9SShreyansh Jain cpu_relax();
531f38f61e9SShreyansh Jain if (!(bm_res->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT)) {
532f38f61e9SShreyansh Jain /* Pool is empty */
533f38f61e9SShreyansh Jain stop = true;
534*6d589905SDavid Marchand }
535f38f61e9SShreyansh Jain };
536f38f61e9SShreyansh Jain return 0;
537f38f61e9SShreyansh Jain }
538f38f61e9SShreyansh Jain
539f38f61e9SShreyansh Jain #endif /* __BMAN_H */
540