1d81734caSHemant Agrawal /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2c47ff048SShreyansh Jain *
3c47ff048SShreyansh Jain * Copyright 2008-2016 Freescale Semiconductor Inc.
4d81734caSHemant Agrawal * Copyright 2017 NXP
5c47ff048SShreyansh Jain *
6c47ff048SShreyansh Jain */
7c47ff048SShreyansh Jain
8c47ff048SShreyansh Jain #include "qman_priv.h"
9c47ff048SShreyansh Jain
10c47ff048SShreyansh Jain /***************************/
11c47ff048SShreyansh Jain /* Portal register assists */
12c47ff048SShreyansh Jain /***************************/
13c47ff048SShreyansh Jain #define QM_REG_EQCR_PI_CINH 0x3000
14c47ff048SShreyansh Jain #define QM_REG_EQCR_CI_CINH 0x3040
15c47ff048SShreyansh Jain #define QM_REG_EQCR_ITR 0x3080
16c47ff048SShreyansh Jain #define QM_REG_DQRR_PI_CINH 0x3100
17c47ff048SShreyansh Jain #define QM_REG_DQRR_CI_CINH 0x3140
18c47ff048SShreyansh Jain #define QM_REG_DQRR_ITR 0x3180
19c47ff048SShreyansh Jain #define QM_REG_DQRR_DCAP 0x31C0
20c47ff048SShreyansh Jain #define QM_REG_DQRR_SDQCR 0x3200
21c47ff048SShreyansh Jain #define QM_REG_DQRR_VDQCR 0x3240
22c47ff048SShreyansh Jain #define QM_REG_DQRR_PDQCR 0x3280
23c47ff048SShreyansh Jain #define QM_REG_MR_PI_CINH 0x3300
24c47ff048SShreyansh Jain #define QM_REG_MR_CI_CINH 0x3340
25c47ff048SShreyansh Jain #define QM_REG_MR_ITR 0x3380
26c47ff048SShreyansh Jain #define QM_REG_CFG 0x3500
27c47ff048SShreyansh Jain #define QM_REG_ISR 0x3600
28c47ff048SShreyansh Jain #define QM_REG_IIR 0x36C0
29c47ff048SShreyansh Jain #define QM_REG_ITPR 0x3740
30c47ff048SShreyansh Jain
31c47ff048SShreyansh Jain /* Cache-enabled register offsets */
32c47ff048SShreyansh Jain #define QM_CL_EQCR 0x0000
33c47ff048SShreyansh Jain #define QM_CL_DQRR 0x1000
34c47ff048SShreyansh Jain #define QM_CL_MR 0x2000
35c47ff048SShreyansh Jain #define QM_CL_EQCR_PI_CENA 0x3000
36c47ff048SShreyansh Jain #define QM_CL_EQCR_CI_CENA 0x3040
37c47ff048SShreyansh Jain #define QM_CL_DQRR_PI_CENA 0x3100
38c47ff048SShreyansh Jain #define QM_CL_DQRR_CI_CENA 0x3140
39c47ff048SShreyansh Jain #define QM_CL_MR_PI_CENA 0x3300
40c47ff048SShreyansh Jain #define QM_CL_MR_CI_CENA 0x3340
41c47ff048SShreyansh Jain #define QM_CL_CR 0x3800
42c47ff048SShreyansh Jain #define QM_CL_RR0 0x3900
43c47ff048SShreyansh Jain #define QM_CL_RR1 0x3940
44c47ff048SShreyansh Jain
45c47ff048SShreyansh Jain /* BTW, the drivers (and h/w programming model) already obtain the required
46c47ff048SShreyansh Jain * synchronisation for portal accesses via lwsync(), hwsync(), and
47c47ff048SShreyansh Jain * data-dependencies. Use of barrier()s or other order-preserving primitives
48c47ff048SShreyansh Jain * simply degrade performance. Hence the use of the __raw_*() interfaces, which
49c47ff048SShreyansh Jain * simply ensure that the compiler treats the portal registers as volatile (ie.
50c47ff048SShreyansh Jain * non-coherent).
51c47ff048SShreyansh Jain */
52c47ff048SShreyansh Jain
53c47ff048SShreyansh Jain /* Cache-inhibited register access. */
54c47ff048SShreyansh Jain #define __qm_in(qm, o) be32_to_cpu(__raw_readl((qm)->ci + (o)))
55c47ff048SShreyansh Jain #define __qm_out(qm, o, val) __raw_writel((cpu_to_be32(val)), \
56c47ff048SShreyansh Jain (qm)->ci + (o))
57c47ff048SShreyansh Jain #define qm_in(reg) __qm_in(&portal->addr, QM_REG_##reg)
58c47ff048SShreyansh Jain #define qm_out(reg, val) __qm_out(&portal->addr, QM_REG_##reg, val)
59c47ff048SShreyansh Jain
60c47ff048SShreyansh Jain /* Cache-enabled (index) register access */
61c47ff048SShreyansh Jain #define __qm_cl_touch_ro(qm, o) dcbt_ro((qm)->ce + (o))
62c47ff048SShreyansh Jain #define __qm_cl_touch_rw(qm, o) dcbt_rw((qm)->ce + (o))
63c47ff048SShreyansh Jain #define __qm_cl_in(qm, o) be32_to_cpu(__raw_readl((qm)->ce + (o)))
64c47ff048SShreyansh Jain #define __qm_cl_out(qm, o, val) \
65c47ff048SShreyansh Jain do { \
66c47ff048SShreyansh Jain u32 *__tmpclout = (qm)->ce + (o); \
67c47ff048SShreyansh Jain __raw_writel(cpu_to_be32(val), __tmpclout); \
68c47ff048SShreyansh Jain dcbf(__tmpclout); \
69c47ff048SShreyansh Jain } while (0)
70c47ff048SShreyansh Jain #define __qm_cl_invalidate(qm, o) dccivac((qm)->ce + (o))
71c47ff048SShreyansh Jain #define qm_cl_touch_ro(reg) __qm_cl_touch_ro(&portal->addr, QM_CL_##reg##_CENA)
72c47ff048SShreyansh Jain #define qm_cl_touch_rw(reg) __qm_cl_touch_rw(&portal->addr, QM_CL_##reg##_CENA)
73c47ff048SShreyansh Jain #define qm_cl_in(reg) __qm_cl_in(&portal->addr, QM_CL_##reg##_CENA)
74c47ff048SShreyansh Jain #define qm_cl_out(reg, val) __qm_cl_out(&portal->addr, QM_CL_##reg##_CENA, val)
75c47ff048SShreyansh Jain #define qm_cl_invalidate(reg)\
76c47ff048SShreyansh Jain __qm_cl_invalidate(&portal->addr, QM_CL_##reg##_CENA)
77c47ff048SShreyansh Jain
78c47ff048SShreyansh Jain /* Cache-enabled ring access */
79c47ff048SShreyansh Jain #define qm_cl(base, idx) ((void *)base + ((idx) << 6))
80c47ff048SShreyansh Jain
81c47ff048SShreyansh Jain /* Cyclic helper for rings. FIXME: once we are able to do fine-grain perf
82c47ff048SShreyansh Jain * analysis, look at using the "extra" bit in the ring index registers to avoid
83c47ff048SShreyansh Jain * cyclic issues.
84c47ff048SShreyansh Jain */
qm_cyc_diff(u8 ringsize,u8 first,u8 last)85c47ff048SShreyansh Jain static inline u8 qm_cyc_diff(u8 ringsize, u8 first, u8 last)
86c47ff048SShreyansh Jain {
87c47ff048SShreyansh Jain /* 'first' is included, 'last' is excluded */
88c47ff048SShreyansh Jain if (first <= last)
89c47ff048SShreyansh Jain return last - first;
90c47ff048SShreyansh Jain return ringsize + last - first;
91c47ff048SShreyansh Jain }
92c47ff048SShreyansh Jain
93c47ff048SShreyansh Jain /* Portal modes.
94c47ff048SShreyansh Jain * Enum types;
95c47ff048SShreyansh Jain * pmode == production mode
96c47ff048SShreyansh Jain * cmode == consumption mode,
97c47ff048SShreyansh Jain * dmode == h/w dequeue mode.
98c47ff048SShreyansh Jain * Enum values use 3 letter codes. First letter matches the portal mode,
99c47ff048SShreyansh Jain * remaining two letters indicate;
100c47ff048SShreyansh Jain * ci == cache-inhibited portal register
101c47ff048SShreyansh Jain * ce == cache-enabled portal register
102c47ff048SShreyansh Jain * vb == in-band valid-bit (cache-enabled)
103c47ff048SShreyansh Jain * dc == DCA (Discrete Consumption Acknowledgment), DQRR-only
104c47ff048SShreyansh Jain * As for "enum qm_dqrr_dmode", it should be self-explanatory.
105c47ff048SShreyansh Jain */
106c47ff048SShreyansh Jain enum qm_eqcr_pmode { /* matches QCSP_CFG::EPM */
107c47ff048SShreyansh Jain qm_eqcr_pci = 0, /* PI index, cache-inhibited */
108c47ff048SShreyansh Jain qm_eqcr_pce = 1, /* PI index, cache-enabled */
109c47ff048SShreyansh Jain qm_eqcr_pvb = 2 /* valid-bit */
110c47ff048SShreyansh Jain };
111c47ff048SShreyansh Jain
112c47ff048SShreyansh Jain enum qm_dqrr_dmode { /* matches QCSP_CFG::DP */
113c47ff048SShreyansh Jain qm_dqrr_dpush = 0, /* SDQCR + VDQCR */
114c47ff048SShreyansh Jain qm_dqrr_dpull = 1 /* PDQCR */
115c47ff048SShreyansh Jain };
116c47ff048SShreyansh Jain
117c47ff048SShreyansh Jain enum qm_dqrr_pmode { /* s/w-only */
118c47ff048SShreyansh Jain qm_dqrr_pci, /* reads DQRR_PI_CINH */
119c47ff048SShreyansh Jain qm_dqrr_pce, /* reads DQRR_PI_CENA */
120c47ff048SShreyansh Jain qm_dqrr_pvb /* reads valid-bit */
121c47ff048SShreyansh Jain };
122c47ff048SShreyansh Jain
123c47ff048SShreyansh Jain enum qm_dqrr_cmode { /* matches QCSP_CFG::DCM */
124c47ff048SShreyansh Jain qm_dqrr_cci = 0, /* CI index, cache-inhibited */
125c47ff048SShreyansh Jain qm_dqrr_cce = 1, /* CI index, cache-enabled */
126c47ff048SShreyansh Jain qm_dqrr_cdc = 2 /* Discrete Consumption Acknowledgment */
127c47ff048SShreyansh Jain };
128c47ff048SShreyansh Jain
129c47ff048SShreyansh Jain enum qm_mr_pmode { /* s/w-only */
130c47ff048SShreyansh Jain qm_mr_pci, /* reads MR_PI_CINH */
131c47ff048SShreyansh Jain qm_mr_pce, /* reads MR_PI_CENA */
132c47ff048SShreyansh Jain qm_mr_pvb /* reads valid-bit */
133c47ff048SShreyansh Jain };
134c47ff048SShreyansh Jain
135c47ff048SShreyansh Jain enum qm_mr_cmode { /* matches QCSP_CFG::MM */
136c47ff048SShreyansh Jain qm_mr_cci = 0, /* CI index, cache-inhibited */
137c47ff048SShreyansh Jain qm_mr_cce = 1 /* CI index, cache-enabled */
138c47ff048SShreyansh Jain };
139c47ff048SShreyansh Jain
140c47ff048SShreyansh Jain /* ------------------------- */
141c47ff048SShreyansh Jain /* --- Portal structures --- */
142c47ff048SShreyansh Jain
143c47ff048SShreyansh Jain #define QM_EQCR_SIZE 8
144c47ff048SShreyansh Jain #define QM_DQRR_SIZE 16
145c47ff048SShreyansh Jain #define QM_MR_SIZE 8
146c47ff048SShreyansh Jain
147c47ff048SShreyansh Jain struct qm_eqcr {
148c47ff048SShreyansh Jain struct qm_eqcr_entry *ring, *cursor;
149c47ff048SShreyansh Jain u8 ci, available, ithresh, vbit;
150c47ff048SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
151c47ff048SShreyansh Jain u32 busy;
152c47ff048SShreyansh Jain enum qm_eqcr_pmode pmode;
153c47ff048SShreyansh Jain #endif
154c47ff048SShreyansh Jain };
155c47ff048SShreyansh Jain
156c47ff048SShreyansh Jain struct qm_dqrr {
157*f5648825SHemant Agrawal struct qm_dqrr_entry *ring, *cursor;
158c47ff048SShreyansh Jain u8 pi, ci, fill, ithresh, vbit;
159c47ff048SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
160c47ff048SShreyansh Jain enum qm_dqrr_dmode dmode;
161c47ff048SShreyansh Jain enum qm_dqrr_pmode pmode;
162c47ff048SShreyansh Jain enum qm_dqrr_cmode cmode;
163c47ff048SShreyansh Jain #endif
164c47ff048SShreyansh Jain };
165c47ff048SShreyansh Jain
166c47ff048SShreyansh Jain struct qm_mr {
167c47ff048SShreyansh Jain const struct qm_mr_entry *ring, *cursor;
168c47ff048SShreyansh Jain u8 pi, ci, fill, ithresh, vbit;
169c47ff048SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
170c47ff048SShreyansh Jain enum qm_mr_pmode pmode;
171c47ff048SShreyansh Jain enum qm_mr_cmode cmode;
172c47ff048SShreyansh Jain #endif
173c47ff048SShreyansh Jain };
174c47ff048SShreyansh Jain
175c47ff048SShreyansh Jain struct qm_mc {
176c47ff048SShreyansh Jain struct qm_mc_command *cr;
177c47ff048SShreyansh Jain struct qm_mc_result *rr;
178c47ff048SShreyansh Jain u8 rridx, vbit;
179c47ff048SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
180c47ff048SShreyansh Jain enum {
181c47ff048SShreyansh Jain /* Can be _mc_start()ed */
182c47ff048SShreyansh Jain qman_mc_idle,
183c47ff048SShreyansh Jain /* Can be _mc_commit()ed or _mc_abort()ed */
184c47ff048SShreyansh Jain qman_mc_user,
185c47ff048SShreyansh Jain /* Can only be _mc_retry()ed */
186c47ff048SShreyansh Jain qman_mc_hw
187c47ff048SShreyansh Jain } state;
188c47ff048SShreyansh Jain #endif
189c47ff048SShreyansh Jain };
190c47ff048SShreyansh Jain
191c47ff048SShreyansh Jain #define QM_PORTAL_ALIGNMENT ____cacheline_aligned
192c47ff048SShreyansh Jain
193c47ff048SShreyansh Jain struct qm_addr {
194c47ff048SShreyansh Jain void __iomem *ce; /* cache-enabled */
195c47ff048SShreyansh Jain void __iomem *ci; /* cache-inhibited */
196c47ff048SShreyansh Jain };
197c47ff048SShreyansh Jain
198c47ff048SShreyansh Jain struct qm_portal {
199c47ff048SShreyansh Jain struct qm_addr addr;
200c47ff048SShreyansh Jain struct qm_eqcr eqcr;
201c47ff048SShreyansh Jain struct qm_dqrr dqrr;
202c47ff048SShreyansh Jain struct qm_mr mr;
203c47ff048SShreyansh Jain struct qm_mc mc;
204c47ff048SShreyansh Jain } QM_PORTAL_ALIGNMENT;
205c47ff048SShreyansh Jain
206c47ff048SShreyansh Jain /* Bit-wise logic to wrap a ring pointer by clearing the "carry bit" */
207c47ff048SShreyansh Jain #define EQCR_CARRYCLEAR(p) \
208c47ff048SShreyansh Jain (void *)((unsigned long)(p) & (~(unsigned long)(QM_EQCR_SIZE << 6)))
209c47ff048SShreyansh Jain
21062196f4eSThomas Monjalon extern dma_addr_t rte_mem_virt2iova(const void *addr);
211c47ff048SShreyansh Jain
212c47ff048SShreyansh Jain /* Bit-wise logic to convert a ring pointer to a ring index */
EQCR_PTR2IDX(struct qm_eqcr_entry * e)213c47ff048SShreyansh Jain static inline u8 EQCR_PTR2IDX(struct qm_eqcr_entry *e)
214c47ff048SShreyansh Jain {
215c47ff048SShreyansh Jain return ((uintptr_t)e >> 6) & (QM_EQCR_SIZE - 1);
216c47ff048SShreyansh Jain }
217c47ff048SShreyansh Jain
218c47ff048SShreyansh Jain /* Increment the 'cursor' ring pointer, taking 'vbit' into account */
EQCR_INC(struct qm_eqcr * eqcr)219c47ff048SShreyansh Jain static inline void EQCR_INC(struct qm_eqcr *eqcr)
220c47ff048SShreyansh Jain {
221c47ff048SShreyansh Jain /* NB: this is odd-looking, but experiments show that it generates fast
222c47ff048SShreyansh Jain * code with essentially no branching overheads. We increment to the
223c47ff048SShreyansh Jain * next EQCR pointer and handle overflow and 'vbit'.
224c47ff048SShreyansh Jain */
225c47ff048SShreyansh Jain struct qm_eqcr_entry *partial = eqcr->cursor + 1;
226c47ff048SShreyansh Jain
227c47ff048SShreyansh Jain eqcr->cursor = EQCR_CARRYCLEAR(partial);
228c47ff048SShreyansh Jain if (partial != eqcr->cursor)
229c47ff048SShreyansh Jain eqcr->vbit ^= QM_EQCR_VERB_VBIT;
230c47ff048SShreyansh Jain }
231c47ff048SShreyansh Jain
qm_eqcr_start_no_stash(struct qm_portal * portal)232c47ff048SShreyansh Jain static inline struct qm_eqcr_entry *qm_eqcr_start_no_stash(struct qm_portal
233c47ff048SShreyansh Jain *portal)
234c47ff048SShreyansh Jain {
235c47ff048SShreyansh Jain register struct qm_eqcr *eqcr = &portal->eqcr;
236c47ff048SShreyansh Jain
237996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
238c47ff048SShreyansh Jain DPAA_ASSERT(!eqcr->busy);
239996672d3SFerruh Yigit #endif
240c47ff048SShreyansh Jain if (!eqcr->available)
241c47ff048SShreyansh Jain return NULL;
242c47ff048SShreyansh Jain
243c47ff048SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
244c47ff048SShreyansh Jain eqcr->busy = 1;
245c47ff048SShreyansh Jain #endif
246c47ff048SShreyansh Jain
247c47ff048SShreyansh Jain return eqcr->cursor;
248c47ff048SShreyansh Jain }
249c47ff048SShreyansh Jain
qm_eqcr_start_stash(struct qm_portal * portal)250c47ff048SShreyansh Jain static inline struct qm_eqcr_entry *qm_eqcr_start_stash(struct qm_portal
251c47ff048SShreyansh Jain *portal)
252c47ff048SShreyansh Jain {
253c47ff048SShreyansh Jain register struct qm_eqcr *eqcr = &portal->eqcr;
254c47ff048SShreyansh Jain u8 diff, old_ci;
255c47ff048SShreyansh Jain
256996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
257c47ff048SShreyansh Jain DPAA_ASSERT(!eqcr->busy);
258996672d3SFerruh Yigit #endif
259c47ff048SShreyansh Jain if (!eqcr->available) {
260c47ff048SShreyansh Jain old_ci = eqcr->ci;
261c47ff048SShreyansh Jain eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
262c47ff048SShreyansh Jain diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
263c47ff048SShreyansh Jain eqcr->available += diff;
264c47ff048SShreyansh Jain if (!diff)
265c47ff048SShreyansh Jain return NULL;
266c47ff048SShreyansh Jain }
267c47ff048SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
268c47ff048SShreyansh Jain eqcr->busy = 1;
269c47ff048SShreyansh Jain #endif
270c47ff048SShreyansh Jain return eqcr->cursor;
271c47ff048SShreyansh Jain }
272c47ff048SShreyansh Jain
qm_eqcr_abort(struct qm_portal * portal)273c47ff048SShreyansh Jain static inline void qm_eqcr_abort(struct qm_portal *portal)
274c47ff048SShreyansh Jain {
275c47ff048SShreyansh Jain __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
276c47ff048SShreyansh Jain
277c47ff048SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
278996672d3SFerruh Yigit DPAA_ASSERT(eqcr->busy);
279c47ff048SShreyansh Jain eqcr->busy = 0;
280c47ff048SShreyansh Jain #endif
281c47ff048SShreyansh Jain }
282c47ff048SShreyansh Jain
qm_eqcr_pend_and_next(struct qm_portal * portal,u8 myverb)283c47ff048SShreyansh Jain static inline struct qm_eqcr_entry *qm_eqcr_pend_and_next(
284c47ff048SShreyansh Jain struct qm_portal *portal, u8 myverb)
285c47ff048SShreyansh Jain {
286c47ff048SShreyansh Jain register struct qm_eqcr *eqcr = &portal->eqcr;
287c47ff048SShreyansh Jain
288996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
289c47ff048SShreyansh Jain DPAA_ASSERT(eqcr->busy);
290c47ff048SShreyansh Jain DPAA_ASSERT(eqcr->pmode != qm_eqcr_pvb);
291996672d3SFerruh Yigit #endif
292c47ff048SShreyansh Jain if (eqcr->available == 1)
293c47ff048SShreyansh Jain return NULL;
294c47ff048SShreyansh Jain eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
295c47ff048SShreyansh Jain dcbf(eqcr->cursor);
296c47ff048SShreyansh Jain EQCR_INC(eqcr);
297c47ff048SShreyansh Jain eqcr->available--;
298c47ff048SShreyansh Jain return eqcr->cursor;
299c47ff048SShreyansh Jain }
300c47ff048SShreyansh Jain
301c47ff048SShreyansh Jain #define EQCR_COMMIT_CHECKS(eqcr) \
302c47ff048SShreyansh Jain do { \
303c47ff048SShreyansh Jain DPAA_ASSERT(eqcr->busy); \
304c47ff048SShreyansh Jain DPAA_ASSERT(eqcr->cursor->orp == (eqcr->cursor->orp & 0x00ffffff)); \
305c47ff048SShreyansh Jain DPAA_ASSERT(eqcr->cursor->fqid == (eqcr->cursor->fqid & 0x00ffffff)); \
306c47ff048SShreyansh Jain } while (0)
307c47ff048SShreyansh Jain
qm_eqcr_pci_commit(struct qm_portal * portal,u8 myverb)308c47ff048SShreyansh Jain static inline void qm_eqcr_pci_commit(struct qm_portal *portal, u8 myverb)
309c47ff048SShreyansh Jain {
310c47ff048SShreyansh Jain register struct qm_eqcr *eqcr = &portal->eqcr;
311c47ff048SShreyansh Jain
312996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
313c47ff048SShreyansh Jain EQCR_COMMIT_CHECKS(eqcr);
314c47ff048SShreyansh Jain DPAA_ASSERT(eqcr->pmode == qm_eqcr_pci);
315996672d3SFerruh Yigit #endif
316c47ff048SShreyansh Jain eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
317c47ff048SShreyansh Jain EQCR_INC(eqcr);
318c47ff048SShreyansh Jain eqcr->available--;
319c47ff048SShreyansh Jain dcbf(eqcr->cursor);
320c47ff048SShreyansh Jain hwsync();
321c47ff048SShreyansh Jain qm_out(EQCR_PI_CINH, EQCR_PTR2IDX(eqcr->cursor));
322c47ff048SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
323c47ff048SShreyansh Jain eqcr->busy = 0;
324c47ff048SShreyansh Jain #endif
325c47ff048SShreyansh Jain }
326c47ff048SShreyansh Jain
qm_eqcr_pce_prefetch(struct qm_portal * portal)327c47ff048SShreyansh Jain static inline void qm_eqcr_pce_prefetch(struct qm_portal *portal)
328c47ff048SShreyansh Jain {
329c47ff048SShreyansh Jain __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
330c47ff048SShreyansh Jain
331996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
332c47ff048SShreyansh Jain DPAA_ASSERT(eqcr->pmode == qm_eqcr_pce);
333996672d3SFerruh Yigit #endif
334c47ff048SShreyansh Jain qm_cl_invalidate(EQCR_PI);
335c47ff048SShreyansh Jain qm_cl_touch_rw(EQCR_PI);
336c47ff048SShreyansh Jain }
337c47ff048SShreyansh Jain
qm_eqcr_pce_commit(struct qm_portal * portal,u8 myverb)338c47ff048SShreyansh Jain static inline void qm_eqcr_pce_commit(struct qm_portal *portal, u8 myverb)
339c47ff048SShreyansh Jain {
340c47ff048SShreyansh Jain register struct qm_eqcr *eqcr = &portal->eqcr;
341c47ff048SShreyansh Jain
342996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
343c47ff048SShreyansh Jain EQCR_COMMIT_CHECKS(eqcr);
344c47ff048SShreyansh Jain DPAA_ASSERT(eqcr->pmode == qm_eqcr_pce);
345996672d3SFerruh Yigit #endif
346c47ff048SShreyansh Jain eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
347c47ff048SShreyansh Jain EQCR_INC(eqcr);
348c47ff048SShreyansh Jain eqcr->available--;
349c47ff048SShreyansh Jain dcbf(eqcr->cursor);
350c47ff048SShreyansh Jain lwsync();
351c47ff048SShreyansh Jain qm_cl_out(EQCR_PI, EQCR_PTR2IDX(eqcr->cursor));
352c47ff048SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
353c47ff048SShreyansh Jain eqcr->busy = 0;
354c47ff048SShreyansh Jain #endif
355c47ff048SShreyansh Jain }
356c47ff048SShreyansh Jain
qm_eqcr_pvb_commit(struct qm_portal * portal,u8 myverb)357c47ff048SShreyansh Jain static inline void qm_eqcr_pvb_commit(struct qm_portal *portal, u8 myverb)
358c47ff048SShreyansh Jain {
359c47ff048SShreyansh Jain register struct qm_eqcr *eqcr = &portal->eqcr;
360c47ff048SShreyansh Jain struct qm_eqcr_entry *eqcursor;
361c47ff048SShreyansh Jain
362996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
363c47ff048SShreyansh Jain EQCR_COMMIT_CHECKS(eqcr);
364c47ff048SShreyansh Jain DPAA_ASSERT(eqcr->pmode == qm_eqcr_pvb);
365996672d3SFerruh Yigit #endif
366c47ff048SShreyansh Jain lwsync();
367c47ff048SShreyansh Jain eqcursor = eqcr->cursor;
368c47ff048SShreyansh Jain eqcursor->__dont_write_directly__verb = myverb | eqcr->vbit;
369c47ff048SShreyansh Jain dcbf(eqcursor);
370c47ff048SShreyansh Jain EQCR_INC(eqcr);
371c47ff048SShreyansh Jain eqcr->available--;
372c47ff048SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
373c47ff048SShreyansh Jain eqcr->busy = 0;
374c47ff048SShreyansh Jain #endif
375c47ff048SShreyansh Jain }
376c47ff048SShreyansh Jain
qm_eqcr_cci_update(struct qm_portal * portal)377c47ff048SShreyansh Jain static inline u8 qm_eqcr_cci_update(struct qm_portal *portal)
378c47ff048SShreyansh Jain {
379c47ff048SShreyansh Jain register struct qm_eqcr *eqcr = &portal->eqcr;
380c47ff048SShreyansh Jain u8 diff, old_ci = eqcr->ci;
381c47ff048SShreyansh Jain
382c47ff048SShreyansh Jain eqcr->ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
383c47ff048SShreyansh Jain diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
384c47ff048SShreyansh Jain eqcr->available += diff;
385c47ff048SShreyansh Jain return diff;
386c47ff048SShreyansh Jain }
387c47ff048SShreyansh Jain
qm_eqcr_cce_prefetch(struct qm_portal * portal)388c47ff048SShreyansh Jain static inline void qm_eqcr_cce_prefetch(struct qm_portal *portal)
389c47ff048SShreyansh Jain {
390c47ff048SShreyansh Jain __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
391c47ff048SShreyansh Jain
392c47ff048SShreyansh Jain qm_cl_touch_ro(EQCR_CI);
393c47ff048SShreyansh Jain }
394c47ff048SShreyansh Jain
qm_eqcr_cce_update(struct qm_portal * portal)395c47ff048SShreyansh Jain static inline u8 qm_eqcr_cce_update(struct qm_portal *portal)
396c47ff048SShreyansh Jain {
397c47ff048SShreyansh Jain register struct qm_eqcr *eqcr = &portal->eqcr;
398c47ff048SShreyansh Jain u8 diff, old_ci = eqcr->ci;
399c47ff048SShreyansh Jain
400c47ff048SShreyansh Jain eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
401c47ff048SShreyansh Jain qm_cl_invalidate(EQCR_CI);
402c47ff048SShreyansh Jain diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
403c47ff048SShreyansh Jain eqcr->available += diff;
404c47ff048SShreyansh Jain return diff;
405c47ff048SShreyansh Jain }
406c47ff048SShreyansh Jain
qm_eqcr_get_ithresh(struct qm_portal * portal)407c47ff048SShreyansh Jain static inline u8 qm_eqcr_get_ithresh(struct qm_portal *portal)
408c47ff048SShreyansh Jain {
409c47ff048SShreyansh Jain register struct qm_eqcr *eqcr = &portal->eqcr;
410c47ff048SShreyansh Jain
411c47ff048SShreyansh Jain return eqcr->ithresh;
412c47ff048SShreyansh Jain }
413c47ff048SShreyansh Jain
qm_eqcr_set_ithresh(struct qm_portal * portal,u8 ithresh)414c47ff048SShreyansh Jain static inline void qm_eqcr_set_ithresh(struct qm_portal *portal, u8 ithresh)
415c47ff048SShreyansh Jain {
416c47ff048SShreyansh Jain register struct qm_eqcr *eqcr = &portal->eqcr;
417c47ff048SShreyansh Jain
418c47ff048SShreyansh Jain eqcr->ithresh = ithresh;
419c47ff048SShreyansh Jain qm_out(EQCR_ITR, ithresh);
420c47ff048SShreyansh Jain }
421c47ff048SShreyansh Jain
qm_eqcr_get_avail(struct qm_portal * portal)422c47ff048SShreyansh Jain static inline u8 qm_eqcr_get_avail(struct qm_portal *portal)
423c47ff048SShreyansh Jain {
424c47ff048SShreyansh Jain register struct qm_eqcr *eqcr = &portal->eqcr;
425c47ff048SShreyansh Jain
426c47ff048SShreyansh Jain return eqcr->available;
427c47ff048SShreyansh Jain }
428c47ff048SShreyansh Jain
qm_eqcr_get_fill(struct qm_portal * portal)429c47ff048SShreyansh Jain static inline u8 qm_eqcr_get_fill(struct qm_portal *portal)
430c47ff048SShreyansh Jain {
431c47ff048SShreyansh Jain register struct qm_eqcr *eqcr = &portal->eqcr;
432c47ff048SShreyansh Jain
433c47ff048SShreyansh Jain return QM_EQCR_SIZE - 1 - eqcr->available;
434c47ff048SShreyansh Jain }
435c47ff048SShreyansh Jain
436c47ff048SShreyansh Jain #define DQRR_CARRYCLEAR(p) \
437c47ff048SShreyansh Jain (void *)((unsigned long)(p) & (~(unsigned long)(QM_DQRR_SIZE << 6)))
438c47ff048SShreyansh Jain
DQRR_PTR2IDX(const struct qm_dqrr_entry * e)439c47ff048SShreyansh Jain static inline u8 DQRR_PTR2IDX(const struct qm_dqrr_entry *e)
440c47ff048SShreyansh Jain {
441c47ff048SShreyansh Jain return ((uintptr_t)e >> 6) & (QM_DQRR_SIZE - 1);
442c47ff048SShreyansh Jain }
443c47ff048SShreyansh Jain
DQRR_INC(const struct qm_dqrr_entry * e)444*f5648825SHemant Agrawal static inline struct qm_dqrr_entry *DQRR_INC(
445c47ff048SShreyansh Jain const struct qm_dqrr_entry *e)
446c47ff048SShreyansh Jain {
447c47ff048SShreyansh Jain return DQRR_CARRYCLEAR(e + 1);
448c47ff048SShreyansh Jain }
449c47ff048SShreyansh Jain
qm_dqrr_set_maxfill(struct qm_portal * portal,u8 mf)450c47ff048SShreyansh Jain static inline void qm_dqrr_set_maxfill(struct qm_portal *portal, u8 mf)
451c47ff048SShreyansh Jain {
452c47ff048SShreyansh Jain qm_out(CFG, (qm_in(CFG) & 0xff0fffff) |
453c47ff048SShreyansh Jain ((mf & (QM_DQRR_SIZE - 1)) << 20));
454c47ff048SShreyansh Jain }
455c47ff048SShreyansh Jain
qm_dqrr_current(struct qm_portal * portal)456c47ff048SShreyansh Jain static inline const struct qm_dqrr_entry *qm_dqrr_current(
457c47ff048SShreyansh Jain struct qm_portal *portal)
458c47ff048SShreyansh Jain {
459c47ff048SShreyansh Jain register struct qm_dqrr *dqrr = &portal->dqrr;
460c47ff048SShreyansh Jain
461c47ff048SShreyansh Jain if (!dqrr->fill)
462c47ff048SShreyansh Jain return NULL;
463c47ff048SShreyansh Jain return dqrr->cursor;
464c47ff048SShreyansh Jain }
465c47ff048SShreyansh Jain
qm_dqrr_cursor(struct qm_portal * portal)466c47ff048SShreyansh Jain static inline u8 qm_dqrr_cursor(struct qm_portal *portal)
467c47ff048SShreyansh Jain {
468c47ff048SShreyansh Jain register struct qm_dqrr *dqrr = &portal->dqrr;
469c47ff048SShreyansh Jain
470c47ff048SShreyansh Jain return DQRR_PTR2IDX(dqrr->cursor);
471c47ff048SShreyansh Jain }
472c47ff048SShreyansh Jain
qm_dqrr_next(struct qm_portal * portal)473c47ff048SShreyansh Jain static inline u8 qm_dqrr_next(struct qm_portal *portal)
474c47ff048SShreyansh Jain {
475c47ff048SShreyansh Jain register struct qm_dqrr *dqrr = &portal->dqrr;
476c47ff048SShreyansh Jain
477c47ff048SShreyansh Jain DPAA_ASSERT(dqrr->fill);
478c47ff048SShreyansh Jain dqrr->cursor = DQRR_INC(dqrr->cursor);
479c47ff048SShreyansh Jain return --dqrr->fill;
480c47ff048SShreyansh Jain }
481c47ff048SShreyansh Jain
qm_dqrr_pci_update(struct qm_portal * portal)482c47ff048SShreyansh Jain static inline u8 qm_dqrr_pci_update(struct qm_portal *portal)
483c47ff048SShreyansh Jain {
484c47ff048SShreyansh Jain register struct qm_dqrr *dqrr = &portal->dqrr;
485c47ff048SShreyansh Jain u8 diff, old_pi = dqrr->pi;
486c47ff048SShreyansh Jain
487996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
488c47ff048SShreyansh Jain DPAA_ASSERT(dqrr->pmode == qm_dqrr_pci);
489996672d3SFerruh Yigit #endif
490c47ff048SShreyansh Jain dqrr->pi = qm_in(DQRR_PI_CINH) & (QM_DQRR_SIZE - 1);
491c47ff048SShreyansh Jain diff = qm_cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi);
492c47ff048SShreyansh Jain dqrr->fill += diff;
493c47ff048SShreyansh Jain return diff;
494c47ff048SShreyansh Jain }
495c47ff048SShreyansh Jain
qm_dqrr_pce_prefetch(struct qm_portal * portal)496c47ff048SShreyansh Jain static inline void qm_dqrr_pce_prefetch(struct qm_portal *portal)
497c47ff048SShreyansh Jain {
498c47ff048SShreyansh Jain __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
499c47ff048SShreyansh Jain
500996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
501c47ff048SShreyansh Jain DPAA_ASSERT(dqrr->pmode == qm_dqrr_pce);
502996672d3SFerruh Yigit #endif
503c47ff048SShreyansh Jain qm_cl_invalidate(DQRR_PI);
504c47ff048SShreyansh Jain qm_cl_touch_ro(DQRR_PI);
505c47ff048SShreyansh Jain }
506c47ff048SShreyansh Jain
qm_dqrr_pce_update(struct qm_portal * portal)507c47ff048SShreyansh Jain static inline u8 qm_dqrr_pce_update(struct qm_portal *portal)
508c47ff048SShreyansh Jain {
509c47ff048SShreyansh Jain register struct qm_dqrr *dqrr = &portal->dqrr;
510c47ff048SShreyansh Jain u8 diff, old_pi = dqrr->pi;
511c47ff048SShreyansh Jain
512996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
513c47ff048SShreyansh Jain DPAA_ASSERT(dqrr->pmode == qm_dqrr_pce);
514996672d3SFerruh Yigit #endif
515c47ff048SShreyansh Jain dqrr->pi = qm_cl_in(DQRR_PI) & (QM_DQRR_SIZE - 1);
516c47ff048SShreyansh Jain diff = qm_cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi);
517c47ff048SShreyansh Jain dqrr->fill += diff;
518c47ff048SShreyansh Jain return diff;
519c47ff048SShreyansh Jain }
520c47ff048SShreyansh Jain
qm_dqrr_pvb_update(struct qm_portal * portal)521c47ff048SShreyansh Jain static inline void qm_dqrr_pvb_update(struct qm_portal *portal)
522c47ff048SShreyansh Jain {
523c47ff048SShreyansh Jain register struct qm_dqrr *dqrr = &portal->dqrr;
524c47ff048SShreyansh Jain const struct qm_dqrr_entry *res = qm_cl(dqrr->ring, dqrr->pi);
525c47ff048SShreyansh Jain
526996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
527c47ff048SShreyansh Jain DPAA_ASSERT(dqrr->pmode == qm_dqrr_pvb);
528996672d3SFerruh Yigit #endif
529c47ff048SShreyansh Jain /* when accessing 'verb', use __raw_readb() to ensure that compiler
530c47ff048SShreyansh Jain * inlining doesn't try to optimise out "excess reads".
531c47ff048SShreyansh Jain */
532c47ff048SShreyansh Jain if ((__raw_readb(&res->verb) & QM_DQRR_VERB_VBIT) == dqrr->vbit) {
533c47ff048SShreyansh Jain dqrr->pi = (dqrr->pi + 1) & (QM_DQRR_SIZE - 1);
534c47ff048SShreyansh Jain if (!dqrr->pi)
535c47ff048SShreyansh Jain dqrr->vbit ^= QM_DQRR_VERB_VBIT;
536c47ff048SShreyansh Jain dqrr->fill++;
537c47ff048SShreyansh Jain }
538c47ff048SShreyansh Jain }
539c47ff048SShreyansh Jain
qm_dqrr_cci_consume(struct qm_portal * portal,u8 num)540c47ff048SShreyansh Jain static inline void qm_dqrr_cci_consume(struct qm_portal *portal, u8 num)
541c47ff048SShreyansh Jain {
542c47ff048SShreyansh Jain register struct qm_dqrr *dqrr = &portal->dqrr;
543c47ff048SShreyansh Jain
544996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
545c47ff048SShreyansh Jain DPAA_ASSERT(dqrr->cmode == qm_dqrr_cci);
546996672d3SFerruh Yigit #endif
547c47ff048SShreyansh Jain dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1);
548c47ff048SShreyansh Jain qm_out(DQRR_CI_CINH, dqrr->ci);
549c47ff048SShreyansh Jain }
550c47ff048SShreyansh Jain
qm_dqrr_cci_consume_to_current(struct qm_portal * portal)551c47ff048SShreyansh Jain static inline void qm_dqrr_cci_consume_to_current(struct qm_portal *portal)
552c47ff048SShreyansh Jain {
553c47ff048SShreyansh Jain register struct qm_dqrr *dqrr = &portal->dqrr;
554c47ff048SShreyansh Jain
555996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
556c47ff048SShreyansh Jain DPAA_ASSERT(dqrr->cmode == qm_dqrr_cci);
557996672d3SFerruh Yigit #endif
558c47ff048SShreyansh Jain dqrr->ci = DQRR_PTR2IDX(dqrr->cursor);
559c47ff048SShreyansh Jain qm_out(DQRR_CI_CINH, dqrr->ci);
560c47ff048SShreyansh Jain }
561c47ff048SShreyansh Jain
qm_dqrr_cce_prefetch(struct qm_portal * portal)562c47ff048SShreyansh Jain static inline void qm_dqrr_cce_prefetch(struct qm_portal *portal)
563c47ff048SShreyansh Jain {
564c47ff048SShreyansh Jain __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
565c47ff048SShreyansh Jain
566996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
567c47ff048SShreyansh Jain DPAA_ASSERT(dqrr->cmode == qm_dqrr_cce);
568996672d3SFerruh Yigit #endif
569c47ff048SShreyansh Jain qm_cl_invalidate(DQRR_CI);
570c47ff048SShreyansh Jain qm_cl_touch_rw(DQRR_CI);
571c47ff048SShreyansh Jain }
572c47ff048SShreyansh Jain
qm_dqrr_cce_consume(struct qm_portal * portal,u8 num)573c47ff048SShreyansh Jain static inline void qm_dqrr_cce_consume(struct qm_portal *portal, u8 num)
574c47ff048SShreyansh Jain {
575c47ff048SShreyansh Jain register struct qm_dqrr *dqrr = &portal->dqrr;
576c47ff048SShreyansh Jain
577996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
578c47ff048SShreyansh Jain DPAA_ASSERT(dqrr->cmode == qm_dqrr_cce);
579996672d3SFerruh Yigit #endif
580c47ff048SShreyansh Jain dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1);
581c47ff048SShreyansh Jain qm_cl_out(DQRR_CI, dqrr->ci);
582c47ff048SShreyansh Jain }
583c47ff048SShreyansh Jain
qm_dqrr_cce_consume_to_current(struct qm_portal * portal)584c47ff048SShreyansh Jain static inline void qm_dqrr_cce_consume_to_current(struct qm_portal *portal)
585c47ff048SShreyansh Jain {
586c47ff048SShreyansh Jain register struct qm_dqrr *dqrr = &portal->dqrr;
587c47ff048SShreyansh Jain
588996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
589c47ff048SShreyansh Jain DPAA_ASSERT(dqrr->cmode == qm_dqrr_cce);
590996672d3SFerruh Yigit #endif
591c47ff048SShreyansh Jain dqrr->ci = DQRR_PTR2IDX(dqrr->cursor);
592c47ff048SShreyansh Jain qm_cl_out(DQRR_CI, dqrr->ci);
593c47ff048SShreyansh Jain }
594c47ff048SShreyansh Jain
qm_dqrr_cdc_consume_1(struct qm_portal * portal,u8 idx,int park)595c47ff048SShreyansh Jain static inline void qm_dqrr_cdc_consume_1(struct qm_portal *portal, u8 idx,
596c47ff048SShreyansh Jain int park)
597c47ff048SShreyansh Jain {
598c47ff048SShreyansh Jain __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
599c47ff048SShreyansh Jain
600996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
601c47ff048SShreyansh Jain DPAA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
602996672d3SFerruh Yigit #endif
603c47ff048SShreyansh Jain DPAA_ASSERT(idx < QM_DQRR_SIZE);
604c47ff048SShreyansh Jain qm_out(DQRR_DCAP, (0 << 8) | /* S */
605c47ff048SShreyansh Jain ((park ? 1 : 0) << 6) | /* PK */
606c47ff048SShreyansh Jain idx); /* DCAP_CI */
607c47ff048SShreyansh Jain }
608c47ff048SShreyansh Jain
qm_dqrr_cdc_consume_1ptr(struct qm_portal * portal,const struct qm_dqrr_entry * dq,int park)609c47ff048SShreyansh Jain static inline void qm_dqrr_cdc_consume_1ptr(struct qm_portal *portal,
610c47ff048SShreyansh Jain const struct qm_dqrr_entry *dq,
611c47ff048SShreyansh Jain int park)
612c47ff048SShreyansh Jain {
613c47ff048SShreyansh Jain __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
614c47ff048SShreyansh Jain u8 idx = DQRR_PTR2IDX(dq);
615c47ff048SShreyansh Jain
616996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
617c47ff048SShreyansh Jain DPAA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
618996672d3SFerruh Yigit #endif
619c47ff048SShreyansh Jain DPAA_ASSERT(idx < QM_DQRR_SIZE);
620c47ff048SShreyansh Jain qm_out(DQRR_DCAP, (0 << 8) | /* DQRR_DCAP::S */
621c47ff048SShreyansh Jain ((park ? 1 : 0) << 6) | /* DQRR_DCAP::PK */
622c47ff048SShreyansh Jain idx); /* DQRR_DCAP::DCAP_CI */
623c47ff048SShreyansh Jain }
624c47ff048SShreyansh Jain
qm_dqrr_cdc_consume_n(struct qm_portal * portal,u16 bitmask)625c47ff048SShreyansh Jain static inline void qm_dqrr_cdc_consume_n(struct qm_portal *portal, u16 bitmask)
626c47ff048SShreyansh Jain {
627c47ff048SShreyansh Jain __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
628c47ff048SShreyansh Jain
629996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
630c47ff048SShreyansh Jain DPAA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
631996672d3SFerruh Yigit #endif
632c47ff048SShreyansh Jain qm_out(DQRR_DCAP, (1 << 8) | /* DQRR_DCAP::S */
633c47ff048SShreyansh Jain ((u32)bitmask << 16)); /* DQRR_DCAP::DCAP_CI */
634c47ff048SShreyansh Jain dqrr->ci = qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
635c47ff048SShreyansh Jain dqrr->fill = qm_cyc_diff(QM_DQRR_SIZE, dqrr->ci, dqrr->pi);
636c47ff048SShreyansh Jain }
637c47ff048SShreyansh Jain
qm_dqrr_cdc_cci(struct qm_portal * portal)638c47ff048SShreyansh Jain static inline u8 qm_dqrr_cdc_cci(struct qm_portal *portal)
639c47ff048SShreyansh Jain {
640c47ff048SShreyansh Jain __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
641c47ff048SShreyansh Jain
642996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
643c47ff048SShreyansh Jain DPAA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
644996672d3SFerruh Yigit #endif
645c47ff048SShreyansh Jain return qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
646c47ff048SShreyansh Jain }
647c47ff048SShreyansh Jain
qm_dqrr_cdc_cce_prefetch(struct qm_portal * portal)648c47ff048SShreyansh Jain static inline void qm_dqrr_cdc_cce_prefetch(struct qm_portal *portal)
649c47ff048SShreyansh Jain {
650c47ff048SShreyansh Jain __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
651c47ff048SShreyansh Jain
652996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
653c47ff048SShreyansh Jain DPAA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
654996672d3SFerruh Yigit #endif
655c47ff048SShreyansh Jain qm_cl_invalidate(DQRR_CI);
656c47ff048SShreyansh Jain qm_cl_touch_ro(DQRR_CI);
657c47ff048SShreyansh Jain }
658c47ff048SShreyansh Jain
qm_dqrr_cdc_cce(struct qm_portal * portal)659c47ff048SShreyansh Jain static inline u8 qm_dqrr_cdc_cce(struct qm_portal *portal)
660c47ff048SShreyansh Jain {
661c47ff048SShreyansh Jain __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
662c47ff048SShreyansh Jain
663996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
664c47ff048SShreyansh Jain DPAA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
665996672d3SFerruh Yigit #endif
666c47ff048SShreyansh Jain return qm_cl_in(DQRR_CI) & (QM_DQRR_SIZE - 1);
667c47ff048SShreyansh Jain }
668c47ff048SShreyansh Jain
qm_dqrr_get_ci(struct qm_portal * portal)669c47ff048SShreyansh Jain static inline u8 qm_dqrr_get_ci(struct qm_portal *portal)
670c47ff048SShreyansh Jain {
671c47ff048SShreyansh Jain register struct qm_dqrr *dqrr = &portal->dqrr;
672c47ff048SShreyansh Jain
673996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
674c47ff048SShreyansh Jain DPAA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
675996672d3SFerruh Yigit #endif
676c47ff048SShreyansh Jain return dqrr->ci;
677c47ff048SShreyansh Jain }
678c47ff048SShreyansh Jain
qm_dqrr_park(struct qm_portal * portal,u8 idx)679c47ff048SShreyansh Jain static inline void qm_dqrr_park(struct qm_portal *portal, u8 idx)
680c47ff048SShreyansh Jain {
681c47ff048SShreyansh Jain __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
682c47ff048SShreyansh Jain
683996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
684c47ff048SShreyansh Jain DPAA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
685996672d3SFerruh Yigit #endif
686c47ff048SShreyansh Jain qm_out(DQRR_DCAP, (0 << 8) | /* S */
687c47ff048SShreyansh Jain (1 << 6) | /* PK */
688c47ff048SShreyansh Jain (idx & (QM_DQRR_SIZE - 1))); /* DCAP_CI */
689c47ff048SShreyansh Jain }
690c47ff048SShreyansh Jain
qm_dqrr_park_current(struct qm_portal * portal)691c47ff048SShreyansh Jain static inline void qm_dqrr_park_current(struct qm_portal *portal)
692c47ff048SShreyansh Jain {
693c47ff048SShreyansh Jain register struct qm_dqrr *dqrr = &portal->dqrr;
694c47ff048SShreyansh Jain
695996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
696c47ff048SShreyansh Jain DPAA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
697996672d3SFerruh Yigit #endif
698c47ff048SShreyansh Jain qm_out(DQRR_DCAP, (0 << 8) | /* S */
699c47ff048SShreyansh Jain (1 << 6) | /* PK */
700c47ff048SShreyansh Jain DQRR_PTR2IDX(dqrr->cursor)); /* DCAP_CI */
701c47ff048SShreyansh Jain }
702c47ff048SShreyansh Jain
qm_dqrr_sdqcr_set(struct qm_portal * portal,u32 sdqcr)703c47ff048SShreyansh Jain static inline void qm_dqrr_sdqcr_set(struct qm_portal *portal, u32 sdqcr)
704c47ff048SShreyansh Jain {
705c47ff048SShreyansh Jain qm_out(DQRR_SDQCR, sdqcr);
706c47ff048SShreyansh Jain }
707c47ff048SShreyansh Jain
qm_dqrr_sdqcr_get(struct qm_portal * portal)708c47ff048SShreyansh Jain static inline u32 qm_dqrr_sdqcr_get(struct qm_portal *portal)
709c47ff048SShreyansh Jain {
710c47ff048SShreyansh Jain return qm_in(DQRR_SDQCR);
711c47ff048SShreyansh Jain }
712c47ff048SShreyansh Jain
qm_dqrr_vdqcr_set(struct qm_portal * portal,u32 vdqcr)713c47ff048SShreyansh Jain static inline void qm_dqrr_vdqcr_set(struct qm_portal *portal, u32 vdqcr)
714c47ff048SShreyansh Jain {
715c47ff048SShreyansh Jain qm_out(DQRR_VDQCR, vdqcr);
716c47ff048SShreyansh Jain }
717c47ff048SShreyansh Jain
qm_dqrr_vdqcr_get(struct qm_portal * portal)718c47ff048SShreyansh Jain static inline u32 qm_dqrr_vdqcr_get(struct qm_portal *portal)
719c47ff048SShreyansh Jain {
720c47ff048SShreyansh Jain return qm_in(DQRR_VDQCR);
721c47ff048SShreyansh Jain }
722c47ff048SShreyansh Jain
qm_dqrr_get_ithresh(struct qm_portal * portal)723c47ff048SShreyansh Jain static inline u8 qm_dqrr_get_ithresh(struct qm_portal *portal)
724c47ff048SShreyansh Jain {
725c47ff048SShreyansh Jain register struct qm_dqrr *dqrr = &portal->dqrr;
726c47ff048SShreyansh Jain
727c47ff048SShreyansh Jain return dqrr->ithresh;
728c47ff048SShreyansh Jain }
729c47ff048SShreyansh Jain
qm_dqrr_set_ithresh(struct qm_portal * portal,u8 ithresh)730c47ff048SShreyansh Jain static inline void qm_dqrr_set_ithresh(struct qm_portal *portal, u8 ithresh)
731c47ff048SShreyansh Jain {
732c47ff048SShreyansh Jain qm_out(DQRR_ITR, ithresh);
733c47ff048SShreyansh Jain }
734c47ff048SShreyansh Jain
qm_dqrr_get_maxfill(struct qm_portal * portal)735c47ff048SShreyansh Jain static inline u8 qm_dqrr_get_maxfill(struct qm_portal *portal)
736c47ff048SShreyansh Jain {
737c47ff048SShreyansh Jain return (qm_in(CFG) & 0x00f00000) >> 20;
738c47ff048SShreyansh Jain }
739c47ff048SShreyansh Jain
740c47ff048SShreyansh Jain /* -------------- */
741c47ff048SShreyansh Jain /* --- MR API --- */
742c47ff048SShreyansh Jain
743c47ff048SShreyansh Jain #define MR_CARRYCLEAR(p) \
744c47ff048SShreyansh Jain (void *)((unsigned long)(p) & (~(unsigned long)(QM_MR_SIZE << 6)))
745c47ff048SShreyansh Jain
MR_PTR2IDX(const struct qm_mr_entry * e)746c47ff048SShreyansh Jain static inline u8 MR_PTR2IDX(const struct qm_mr_entry *e)
747c47ff048SShreyansh Jain {
748c47ff048SShreyansh Jain return ((uintptr_t)e >> 6) & (QM_MR_SIZE - 1);
749c47ff048SShreyansh Jain }
750c47ff048SShreyansh Jain
MR_INC(const struct qm_mr_entry * e)751c47ff048SShreyansh Jain static inline const struct qm_mr_entry *MR_INC(const struct qm_mr_entry *e)
752c47ff048SShreyansh Jain {
753c47ff048SShreyansh Jain return MR_CARRYCLEAR(e + 1);
754c47ff048SShreyansh Jain }
755c47ff048SShreyansh Jain
qm_mr_finish(struct qm_portal * portal)756c47ff048SShreyansh Jain static inline void qm_mr_finish(struct qm_portal *portal)
757c47ff048SShreyansh Jain {
758c47ff048SShreyansh Jain register struct qm_mr *mr = &portal->mr;
759c47ff048SShreyansh Jain
760c47ff048SShreyansh Jain if (mr->ci != MR_PTR2IDX(mr->cursor))
761c47ff048SShreyansh Jain pr_crit("Ignoring completed MR entries\n");
762c47ff048SShreyansh Jain }
763c47ff048SShreyansh Jain
qm_mr_current(struct qm_portal * portal)764c47ff048SShreyansh Jain static inline const struct qm_mr_entry *qm_mr_current(struct qm_portal *portal)
765c47ff048SShreyansh Jain {
766c47ff048SShreyansh Jain register struct qm_mr *mr = &portal->mr;
767c47ff048SShreyansh Jain
768c47ff048SShreyansh Jain if (!mr->fill)
769c47ff048SShreyansh Jain return NULL;
770c47ff048SShreyansh Jain return mr->cursor;
771c47ff048SShreyansh Jain }
772c47ff048SShreyansh Jain
qm_mr_next(struct qm_portal * portal)773c47ff048SShreyansh Jain static inline u8 qm_mr_next(struct qm_portal *portal)
774c47ff048SShreyansh Jain {
775c47ff048SShreyansh Jain register struct qm_mr *mr = &portal->mr;
776c47ff048SShreyansh Jain
777c47ff048SShreyansh Jain DPAA_ASSERT(mr->fill);
778c47ff048SShreyansh Jain mr->cursor = MR_INC(mr->cursor);
779c47ff048SShreyansh Jain return --mr->fill;
780c47ff048SShreyansh Jain }
781c47ff048SShreyansh Jain
qm_mr_cci_consume(struct qm_portal * portal,u8 num)782c47ff048SShreyansh Jain static inline void qm_mr_cci_consume(struct qm_portal *portal, u8 num)
783c47ff048SShreyansh Jain {
784c47ff048SShreyansh Jain register struct qm_mr *mr = &portal->mr;
785c47ff048SShreyansh Jain
786996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
787c47ff048SShreyansh Jain DPAA_ASSERT(mr->cmode == qm_mr_cci);
788996672d3SFerruh Yigit #endif
789c47ff048SShreyansh Jain mr->ci = (mr->ci + num) & (QM_MR_SIZE - 1);
790c47ff048SShreyansh Jain qm_out(MR_CI_CINH, mr->ci);
791c47ff048SShreyansh Jain }
792c47ff048SShreyansh Jain
qm_mr_cci_consume_to_current(struct qm_portal * portal)793c47ff048SShreyansh Jain static inline void qm_mr_cci_consume_to_current(struct qm_portal *portal)
794c47ff048SShreyansh Jain {
795c47ff048SShreyansh Jain register struct qm_mr *mr = &portal->mr;
796c47ff048SShreyansh Jain
797996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
798c47ff048SShreyansh Jain DPAA_ASSERT(mr->cmode == qm_mr_cci);
799996672d3SFerruh Yigit #endif
800c47ff048SShreyansh Jain mr->ci = MR_PTR2IDX(mr->cursor);
801c47ff048SShreyansh Jain qm_out(MR_CI_CINH, mr->ci);
802c47ff048SShreyansh Jain }
803c47ff048SShreyansh Jain
qm_mr_set_ithresh(struct qm_portal * portal,u8 ithresh)804c47ff048SShreyansh Jain static inline void qm_mr_set_ithresh(struct qm_portal *portal, u8 ithresh)
805c47ff048SShreyansh Jain {
806c47ff048SShreyansh Jain qm_out(MR_ITR, ithresh);
807c47ff048SShreyansh Jain }
808c47ff048SShreyansh Jain
809c47ff048SShreyansh Jain /* ------------------------------ */
810c47ff048SShreyansh Jain /* --- Management command API --- */
qm_mc_init(struct qm_portal * portal)811c47ff048SShreyansh Jain static inline int qm_mc_init(struct qm_portal *portal)
812c47ff048SShreyansh Jain {
813c47ff048SShreyansh Jain register struct qm_mc *mc = &portal->mc;
814c47ff048SShreyansh Jain
815c47ff048SShreyansh Jain mc->cr = portal->addr.ce + QM_CL_CR;
816c47ff048SShreyansh Jain mc->rr = portal->addr.ce + QM_CL_RR0;
817c47ff048SShreyansh Jain mc->rridx = (__raw_readb(&mc->cr->__dont_write_directly__verb) &
818c47ff048SShreyansh Jain QM_MCC_VERB_VBIT) ? 0 : 1;
819c47ff048SShreyansh Jain mc->vbit = mc->rridx ? QM_MCC_VERB_VBIT : 0;
820c47ff048SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
821c47ff048SShreyansh Jain mc->state = qman_mc_idle;
822c47ff048SShreyansh Jain #endif
823c47ff048SShreyansh Jain return 0;
824c47ff048SShreyansh Jain }
825c47ff048SShreyansh Jain
qm_mc_finish(struct qm_portal * portal)826c47ff048SShreyansh Jain static inline void qm_mc_finish(struct qm_portal *portal)
827c47ff048SShreyansh Jain {
828c47ff048SShreyansh Jain __maybe_unused register struct qm_mc *mc = &portal->mc;
829c47ff048SShreyansh Jain
830c47ff048SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
831996672d3SFerruh Yigit DPAA_ASSERT(mc->state == qman_mc_idle);
832c47ff048SShreyansh Jain if (mc->state != qman_mc_idle)
833c47ff048SShreyansh Jain pr_crit("Losing incomplete MC command\n");
834c47ff048SShreyansh Jain #endif
835c47ff048SShreyansh Jain }
836c47ff048SShreyansh Jain
qm_mc_start(struct qm_portal * portal)837c47ff048SShreyansh Jain static inline struct qm_mc_command *qm_mc_start(struct qm_portal *portal)
838c47ff048SShreyansh Jain {
839c47ff048SShreyansh Jain register struct qm_mc *mc = &portal->mc;
840c47ff048SShreyansh Jain
841c47ff048SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
842996672d3SFerruh Yigit DPAA_ASSERT(mc->state == qman_mc_idle);
843c47ff048SShreyansh Jain mc->state = qman_mc_user;
844c47ff048SShreyansh Jain #endif
845c47ff048SShreyansh Jain dcbz_64(mc->cr);
846c47ff048SShreyansh Jain return mc->cr;
847c47ff048SShreyansh Jain }
848c47ff048SShreyansh Jain
qm_mc_commit(struct qm_portal * portal,u8 myverb)849c47ff048SShreyansh Jain static inline void qm_mc_commit(struct qm_portal *portal, u8 myverb)
850c47ff048SShreyansh Jain {
851c47ff048SShreyansh Jain register struct qm_mc *mc = &portal->mc;
852c47ff048SShreyansh Jain struct qm_mc_result *rr = mc->rr + mc->rridx;
853c47ff048SShreyansh Jain
854996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
855c47ff048SShreyansh Jain DPAA_ASSERT(mc->state == qman_mc_user);
856996672d3SFerruh Yigit #endif
857c47ff048SShreyansh Jain lwsync();
858c47ff048SShreyansh Jain mc->cr->__dont_write_directly__verb = myverb | mc->vbit;
859c47ff048SShreyansh Jain dcbf(mc->cr);
860c47ff048SShreyansh Jain dcbit_ro(rr);
861c47ff048SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
862c47ff048SShreyansh Jain mc->state = qman_mc_hw;
863c47ff048SShreyansh Jain #endif
864c47ff048SShreyansh Jain }
865c47ff048SShreyansh Jain
qm_mc_result(struct qm_portal * portal)866c47ff048SShreyansh Jain static inline struct qm_mc_result *qm_mc_result(struct qm_portal *portal)
867c47ff048SShreyansh Jain {
868c47ff048SShreyansh Jain register struct qm_mc *mc = &portal->mc;
869c47ff048SShreyansh Jain struct qm_mc_result *rr = mc->rr + mc->rridx;
870c47ff048SShreyansh Jain
871996672d3SFerruh Yigit #ifdef RTE_LIBRTE_DPAA_HWDEBUG
872c47ff048SShreyansh Jain DPAA_ASSERT(mc->state == qman_mc_hw);
873996672d3SFerruh Yigit #endif
874c47ff048SShreyansh Jain /* The inactive response register's verb byte always returns zero until
875c47ff048SShreyansh Jain * its command is submitted and completed. This includes the valid-bit,
876c47ff048SShreyansh Jain * in case you were wondering.
877c47ff048SShreyansh Jain */
878c47ff048SShreyansh Jain if (!__raw_readb(&rr->verb)) {
879c47ff048SShreyansh Jain dcbit_ro(rr);
880c47ff048SShreyansh Jain return NULL;
881c47ff048SShreyansh Jain }
882c47ff048SShreyansh Jain mc->rridx ^= 1;
883c47ff048SShreyansh Jain mc->vbit ^= QM_MCC_VERB_VBIT;
884c47ff048SShreyansh Jain #ifdef RTE_LIBRTE_DPAA_HWDEBUG
885c47ff048SShreyansh Jain mc->state = qman_mc_idle;
886c47ff048SShreyansh Jain #endif
887c47ff048SShreyansh Jain return rr;
888c47ff048SShreyansh Jain }
889c47ff048SShreyansh Jain
890c47ff048SShreyansh Jain /* Portal interrupt register API */
qm_isr_set_iperiod(struct qm_portal * portal,u16 iperiod)891c47ff048SShreyansh Jain static inline void qm_isr_set_iperiod(struct qm_portal *portal, u16 iperiod)
892c47ff048SShreyansh Jain {
893c47ff048SShreyansh Jain qm_out(ITPR, iperiod);
894c47ff048SShreyansh Jain }
895c47ff048SShreyansh Jain
__qm_isr_read(struct qm_portal * portal,enum qm_isr_reg n)896c47ff048SShreyansh Jain static inline u32 __qm_isr_read(struct qm_portal *portal, enum qm_isr_reg n)
897c47ff048SShreyansh Jain {
898c47ff048SShreyansh Jain #if defined(RTE_ARCH_ARM64)
899c47ff048SShreyansh Jain return __qm_in(&portal->addr, QM_REG_ISR + (n << 6));
900c47ff048SShreyansh Jain #else
901c47ff048SShreyansh Jain return __qm_in(&portal->addr, QM_REG_ISR + (n << 2));
902c47ff048SShreyansh Jain #endif
903c47ff048SShreyansh Jain }
904c47ff048SShreyansh Jain
__qm_isr_write(struct qm_portal * portal,enum qm_isr_reg n,u32 val)905c47ff048SShreyansh Jain static inline void __qm_isr_write(struct qm_portal *portal, enum qm_isr_reg n,
906c47ff048SShreyansh Jain u32 val)
907c47ff048SShreyansh Jain {
908c47ff048SShreyansh Jain #if defined(RTE_ARCH_ARM64)
909c47ff048SShreyansh Jain __qm_out(&portal->addr, QM_REG_ISR + (n << 6), val);
910c47ff048SShreyansh Jain #else
911c47ff048SShreyansh Jain __qm_out(&portal->addr, QM_REG_ISR + (n << 2), val);
912c47ff048SShreyansh Jain #endif
913c47ff048SShreyansh Jain }
914