Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'soc-fsl-next-v5.7' of git://git.kernel.org/pub/scm/linux/kernel/git/leo/linux into arm/drivers

NXP/FSL SoC driver updates for v5.7

DPAA2 DPIO driver performance optimization
- Add and use QMAN multiple enqueue interface
- Use function pointer indirection to replace checks in hotpath

QUICC Engine drivers
- Fix sparse warnings and exposed endian issues

* tag 'soc-fsl-next-v5.7' of git://git.kernel.org/pub/scm/linux/kernel/git/leo/linux:
soc: fsl: qe: fix sparse warnings for ucc_slow.c
soc: fsl: qe: ucc_slow: remove 0 assignment for kzalloc'ed structure
soc: fsl: qe: fix sparse warnings for ucc_fast.c
soc: fsl: qe: fix sparse warnings for qe_ic.c
soc: fsl: qe: fix sparse warnings for ucc.c
soc: fsl: qe: fix sparse warning for qe_common.c
soc: fsl: qe: fix sparse warnings for qe.c
soc: fsl: dpio: fix dereference of pointer p before null check
soc: fsl: dpio: Replace QMAN array mode with ring mode enqueue
soc: fsl: dpio: QMAN performance improvement with function pointer indirection
soc: fsl: dpio: Adding QMAN multiple enqueue interface

Link: https://lore.kernel.org/r/20200326001257.22696-1-leoyang.li@nxp.com
Signed-off-by: Arnd Bergmann <arnd@arndb.de>

+936 -128
+66 -3
drivers/soc/fsl/dpio/dpio-service.c
··· 1 1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 2 2 /* 3 3 * Copyright 2014-2016 Freescale Semiconductor Inc. 4 - * Copyright 2016 NXP 4 + * Copyright 2016-2019 NXP 5 5 * 6 6 */ 7 7 #include <linux/types.h> ··· 433 433 EXPORT_SYMBOL(dpaa2_io_service_enqueue_fq); 434 434 435 435 /** 436 + * dpaa2_io_service_enqueue_multiple_fq() - Enqueue multiple frames 437 + * to a frame queue using one fqid. 438 + * @d: the given DPIO service. 439 + * @fqid: the given frame queue id. 440 + * @fd: the frame descriptor which is enqueued. 441 + * @nb: number of frames to be enqueud 442 + * 443 + * Return 0 for successful enqueue, -EBUSY if the enqueue ring is not ready, 444 + * or -ENODEV if there is no dpio service. 445 + */ 446 + int dpaa2_io_service_enqueue_multiple_fq(struct dpaa2_io *d, 447 + u32 fqid, 448 + const struct dpaa2_fd *fd, 449 + int nb) 450 + { 451 + struct qbman_eq_desc ed; 452 + 453 + d = service_select(d); 454 + if (!d) 455 + return -ENODEV; 456 + 457 + qbman_eq_desc_clear(&ed); 458 + qbman_eq_desc_set_no_orp(&ed, 0); 459 + qbman_eq_desc_set_fq(&ed, fqid); 460 + 461 + return qbman_swp_enqueue_multiple(d->swp, &ed, fd, 0, nb); 462 + } 463 + EXPORT_SYMBOL(dpaa2_io_service_enqueue_multiple_fq); 464 + 465 + /** 466 + * dpaa2_io_service_enqueue_multiple_desc_fq() - Enqueue multiple frames 467 + * to different frame queue using a list of fqids. 468 + * @d: the given DPIO service. 469 + * @fqid: the given list of frame queue ids. 470 + * @fd: the frame descriptor which is enqueued. 471 + * @nb: number of frames to be enqueud 472 + * 473 + * Return 0 for successful enqueue, -EBUSY if the enqueue ring is not ready, 474 + * or -ENODEV if there is no dpio service. 475 + */ 476 + int dpaa2_io_service_enqueue_multiple_desc_fq(struct dpaa2_io *d, 477 + u32 *fqid, 478 + const struct dpaa2_fd *fd, 479 + int nb) 480 + { 481 + int i; 482 + struct qbman_eq_desc ed[32]; 483 + 484 + d = service_select(d); 485 + if (!d) 486 + return -ENODEV; 487 + 488 + for (i = 0; i < nb; i++) { 489 + qbman_eq_desc_clear(&ed[i]); 490 + qbman_eq_desc_set_no_orp(&ed[i], 0); 491 + qbman_eq_desc_set_fq(&ed[i], fqid[i]); 492 + } 493 + 494 + return qbman_swp_enqueue_multiple_desc(d->swp, &ed[0], fd, nb); 495 + } 496 + EXPORT_SYMBOL(dpaa2_io_service_enqueue_multiple_desc_fq); 497 + 498 + /** 436 499 * dpaa2_io_service_enqueue_qd() - Enqueue a frame to a QD. 437 500 * @d: the given DPIO service. 438 501 * @qdid: the given queuing destination id. ··· 589 526 590 527 /** 591 528 * dpaa2_io_store_create() - Create the dma memory storage for dequeue result. 592 - * @max_frames: the maximum number of dequeued result for frames, must be <= 16. 529 + * @max_frames: the maximum number of dequeued result for frames, must be <= 32. 593 530 * @dev: the device to allow mapping/unmapping the DMAable region. 594 531 * 595 532 * The size of the storage is "max_frames*sizeof(struct dpaa2_dq)". ··· 604 541 struct dpaa2_io_store *ret; 605 542 size_t size; 606 543 607 - if (!max_frames || (max_frames > 16)) 544 + if (!max_frames || (max_frames > 32)) 608 545 return NULL; 609 546 610 547 ret = kmalloc(sizeof(*ret), GFP_KERNEL);
+687 -82
drivers/soc/fsl/dpio/qbman-portal.c
··· 1 1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 2 2 /* 3 3 * Copyright (C) 2014-2016 Freescale Semiconductor, Inc. 4 - * Copyright 2016 NXP 4 + * Copyright 2016-2019 NXP 5 5 * 6 6 */ 7 7 8 8 #include <asm/cacheflush.h> 9 9 #include <linux/io.h> 10 10 #include <linux/slab.h> 11 + #include <linux/spinlock.h> 11 12 #include <soc/fsl/dpaa2-global.h> 12 13 13 14 #include "qbman-portal.h" 14 - 15 - #define QMAN_REV_4000 0x04000000 16 - #define QMAN_REV_4100 0x04010000 17 - #define QMAN_REV_4101 0x04010001 18 - #define QMAN_REV_5000 0x05000000 19 - 20 - #define QMAN_REV_MASK 0xffff0000 21 15 22 16 /* All QBMan command and result structures use this "valid bit" encoding */ 23 17 #define QB_VALID_BIT ((u32)0x80) ··· 22 28 23 29 /* CINH register offsets */ 24 30 #define QBMAN_CINH_SWP_EQCR_PI 0x800 31 + #define QBMAN_CINH_SWP_EQCR_CI 0x840 25 32 #define QBMAN_CINH_SWP_EQAR 0x8c0 26 33 #define QBMAN_CINH_SWP_CR_RT 0x900 27 34 #define QBMAN_CINH_SWP_VDQCR_RT 0x940 ··· 46 51 #define QBMAN_CENA_SWP_CR 0x600 47 52 #define QBMAN_CENA_SWP_RR(vb) (0x700 + ((u32)(vb) >> 1)) 48 53 #define QBMAN_CENA_SWP_VDQCR 0x780 54 + #define QBMAN_CENA_SWP_EQCR_CI 0x840 55 + #define QBMAN_CENA_SWP_EQCR_CI_MEMBACK 0x1840 49 56 50 57 /* CENA register offsets in memory-backed mode */ 51 58 #define QBMAN_CENA_SWP_DQRR_MEM(n) (0x800 + ((u32)(n) << 6)) ··· 75 78 /* opaque token for static dequeues */ 76 79 #define QMAN_SDQCR_TOKEN 0xbb 77 80 81 + #define QBMAN_EQCR_DCA_IDXMASK 0x0f 82 + #define QBMAN_ENQUEUE_FLAG_DCA (1ULL << 31) 83 + 84 + #define EQ_DESC_SIZE_WITHOUT_FD 29 85 + #define EQ_DESC_SIZE_FD_START 32 86 + 78 87 enum qbman_sdqcr_dct { 79 88 qbman_sdqcr_dct_null = 0, 80 89 qbman_sdqcr_dct_prio_ics, ··· 92 89 qbman_sdqcr_fc_one = 0, 93 90 qbman_sdqcr_fc_up_to_3 = 1 94 91 }; 92 + 93 + /* Internal Function declaration */ 94 + static int qbman_swp_enqueue_direct(struct qbman_swp *s, 95 + const struct qbman_eq_desc *d, 96 + const struct dpaa2_fd *fd); 97 + static int qbman_swp_enqueue_mem_back(struct qbman_swp *s, 98 + const struct qbman_eq_desc *d, 99 + const struct dpaa2_fd *fd); 100 + static int qbman_swp_enqueue_multiple_direct(struct qbman_swp *s, 101 + const struct qbman_eq_desc *d, 102 + const struct dpaa2_fd *fd, 103 + uint32_t *flags, 104 + int num_frames); 105 + static int qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s, 106 + const struct qbman_eq_desc *d, 107 + const struct dpaa2_fd *fd, 108 + uint32_t *flags, 109 + int num_frames); 110 + static int 111 + qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp *s, 112 + const struct qbman_eq_desc *d, 113 + const struct dpaa2_fd *fd, 114 + int num_frames); 115 + static 116 + int qbman_swp_enqueue_multiple_desc_mem_back(struct qbman_swp *s, 117 + const struct qbman_eq_desc *d, 118 + const struct dpaa2_fd *fd, 119 + int num_frames); 120 + static int qbman_swp_pull_direct(struct qbman_swp *s, 121 + struct qbman_pull_desc *d); 122 + static int qbman_swp_pull_mem_back(struct qbman_swp *s, 123 + struct qbman_pull_desc *d); 124 + 125 + const struct dpaa2_dq *qbman_swp_dqrr_next_direct(struct qbman_swp *s); 126 + const struct dpaa2_dq *qbman_swp_dqrr_next_mem_back(struct qbman_swp *s); 127 + 128 + static int qbman_swp_release_direct(struct qbman_swp *s, 129 + const struct qbman_release_desc *d, 130 + const u64 *buffers, 131 + unsigned int num_buffers); 132 + static int qbman_swp_release_mem_back(struct qbman_swp *s, 133 + const struct qbman_release_desc *d, 134 + const u64 *buffers, 135 + unsigned int num_buffers); 136 + 137 + /* Function pointers */ 138 + int (*qbman_swp_enqueue_ptr)(struct qbman_swp *s, 139 + const struct qbman_eq_desc *d, 140 + const struct dpaa2_fd *fd) 141 + = qbman_swp_enqueue_direct; 142 + 143 + int (*qbman_swp_enqueue_multiple_ptr)(struct qbman_swp *s, 144 + const struct qbman_eq_desc *d, 145 + const struct dpaa2_fd *fd, 146 + uint32_t *flags, 147 + int num_frames) 148 + = qbman_swp_enqueue_multiple_direct; 149 + 150 + int 151 + (*qbman_swp_enqueue_multiple_desc_ptr)(struct qbman_swp *s, 152 + const struct qbman_eq_desc *d, 153 + const struct dpaa2_fd *fd, 154 + int num_frames) 155 + = qbman_swp_enqueue_multiple_desc_direct; 156 + 157 + int (*qbman_swp_pull_ptr)(struct qbman_swp *s, struct qbman_pull_desc *d) 158 + = qbman_swp_pull_direct; 159 + 160 + const struct dpaa2_dq *(*qbman_swp_dqrr_next_ptr)(struct qbman_swp *s) 161 + = qbman_swp_dqrr_next_direct; 162 + 163 + int (*qbman_swp_release_ptr)(struct qbman_swp *s, 164 + const struct qbman_release_desc *d, 165 + const u64 *buffers, 166 + unsigned int num_buffers) 167 + = qbman_swp_release_direct; 95 168 96 169 /* Portal Access */ 97 170 ··· 225 146 226 147 #define QMAN_RT_MODE 0x00000100 227 148 149 + static inline u8 qm_cyc_diff(u8 ringsize, u8 first, u8 last) 150 + { 151 + /* 'first' is included, 'last' is excluded */ 152 + if (first <= last) 153 + return last - first; 154 + else 155 + return (2 * ringsize) - (first - last); 156 + } 157 + 228 158 /** 229 159 * qbman_swp_init() - Create a functional object representing the given 230 160 * QBMan portal descriptor. ··· 244 156 */ 245 157 struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d) 246 158 { 247 - struct qbman_swp *p = kmalloc(sizeof(*p), GFP_KERNEL); 159 + struct qbman_swp *p = kzalloc(sizeof(*p), GFP_KERNEL); 248 160 u32 reg; 161 + u32 mask_size; 162 + u32 eqcr_pi; 249 163 250 164 if (!p) 251 165 return NULL; 166 + 167 + spin_lock_init(&p->access_spinlock); 168 + 252 169 p->desc = d; 253 170 p->mc.valid_bit = QB_VALID_BIT; 254 171 p->sdq = 0; ··· 279 186 p->addr_cena = d->cena_bar; 280 187 p->addr_cinh = d->cinh_bar; 281 188 282 - if ((p->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) 283 - memset(p->addr_cena, 0, 64 * 1024); 189 + if ((p->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) { 284 190 285 - reg = qbman_set_swp_cfg(p->dqrr.dqrr_size, 286 - 1, /* Writes Non-cacheable */ 287 - 0, /* EQCR_CI stashing threshold */ 288 - 3, /* RPM: Valid bit mode, RCR in array mode */ 289 - 2, /* DCM: Discrete consumption ack mode */ 290 - 3, /* EPM: Valid bit mode, EQCR in array mode */ 291 - 1, /* mem stashing drop enable == TRUE */ 292 - 1, /* mem stashing priority == TRUE */ 293 - 1, /* mem stashing enable == TRUE */ 294 - 1, /* dequeue stashing priority == TRUE */ 295 - 0, /* dequeue stashing enable == FALSE */ 296 - 0); /* EQCR_CI stashing priority == FALSE */ 297 - if ((p->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) 191 + reg = qbman_set_swp_cfg(p->dqrr.dqrr_size, 192 + 1, /* Writes Non-cacheable */ 193 + 0, /* EQCR_CI stashing threshold */ 194 + 3, /* RPM: RCR in array mode */ 195 + 2, /* DCM: Discrete consumption ack */ 196 + 2, /* EPM: EQCR in ring mode */ 197 + 1, /* mem stashing drop enable enable */ 198 + 1, /* mem stashing priority enable */ 199 + 1, /* mem stashing enable */ 200 + 1, /* dequeue stashing priority enable */ 201 + 0, /* dequeue stashing enable enable */ 202 + 0); /* EQCR_CI stashing priority enable */ 203 + } else { 204 + memset(p->addr_cena, 0, 64 * 1024); 205 + reg = qbman_set_swp_cfg(p->dqrr.dqrr_size, 206 + 1, /* Writes Non-cacheable */ 207 + 1, /* EQCR_CI stashing threshold */ 208 + 3, /* RPM: RCR in array mode */ 209 + 2, /* DCM: Discrete consumption ack */ 210 + 0, /* EPM: EQCR in ring mode */ 211 + 1, /* mem stashing drop enable */ 212 + 1, /* mem stashing priority enable */ 213 + 1, /* mem stashing enable */ 214 + 1, /* dequeue stashing priority enable */ 215 + 0, /* dequeue stashing enable */ 216 + 0); /* EQCR_CI stashing priority enable */ 298 217 reg |= 1 << SWP_CFG_CPBS_SHIFT | /* memory-backed mode */ 299 218 1 << SWP_CFG_VPM_SHIFT | /* VDQCR read triggered mode */ 300 219 1 << SWP_CFG_CPM_SHIFT; /* CR read triggered mode */ 220 + } 301 221 302 222 qbman_write_register(p, QBMAN_CINH_SWP_CFG, reg); 303 223 reg = qbman_read_register(p, QBMAN_CINH_SWP_CFG); ··· 331 225 * applied when dequeues from a specific channel are enabled. 332 226 */ 333 227 qbman_write_register(p, QBMAN_CINH_SWP_SDQCR, 0); 228 + 229 + p->eqcr.pi_ring_size = 8; 230 + if ((p->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) { 231 + p->eqcr.pi_ring_size = 32; 232 + qbman_swp_enqueue_ptr = 233 + qbman_swp_enqueue_mem_back; 234 + qbman_swp_enqueue_multiple_ptr = 235 + qbman_swp_enqueue_multiple_mem_back; 236 + qbman_swp_enqueue_multiple_desc_ptr = 237 + qbman_swp_enqueue_multiple_desc_mem_back; 238 + qbman_swp_pull_ptr = qbman_swp_pull_mem_back; 239 + qbman_swp_dqrr_next_ptr = qbman_swp_dqrr_next_mem_back; 240 + qbman_swp_release_ptr = qbman_swp_release_mem_back; 241 + } 242 + 243 + for (mask_size = p->eqcr.pi_ring_size; mask_size > 0; mask_size >>= 1) 244 + p->eqcr.pi_ci_mask = (p->eqcr.pi_ci_mask << 1) + 1; 245 + eqcr_pi = qbman_read_register(p, QBMAN_CINH_SWP_EQCR_PI); 246 + p->eqcr.pi = eqcr_pi & p->eqcr.pi_ci_mask; 247 + p->eqcr.pi_vb = eqcr_pi & QB_VALID_BIT; 248 + p->eqcr.ci = qbman_read_register(p, QBMAN_CINH_SWP_EQCR_CI) 249 + & p->eqcr.pi_ci_mask; 250 + p->eqcr.available = p->eqcr.pi_ring_size; 251 + 334 252 return p; 335 253 } 336 254 ··· 508 378 #define QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT 2 509 379 #define QB_ENQUEUE_CMD_IRQ_ON_DISPATCH_SHIFT 3 510 380 #define QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT 4 381 + #define QB_ENQUEUE_CMD_DCA_EN_SHIFT 7 511 382 512 383 /** 513 384 * qbman_eq_desc_clear() - Clear the contents of a descriptor to ··· 584 453 QMAN_RT_MODE); 585 454 } 586 455 456 + #define QB_RT_BIT ((u32)0x100) 587 457 /** 588 - * qbman_swp_enqueue() - Issue an enqueue command 458 + * qbman_swp_enqueue_direct() - Issue an enqueue command 589 459 * @s: the software portal used for enqueue 590 460 * @d: the enqueue descriptor 591 461 * @fd: the frame descriptor to be enqueued ··· 596 464 * 597 465 * Return 0 for successful enqueue, -EBUSY if the EQCR is not ready. 598 466 */ 599 - int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d, 600 - const struct dpaa2_fd *fd) 467 + static 468 + int qbman_swp_enqueue_direct(struct qbman_swp *s, 469 + const struct qbman_eq_desc *d, 470 + const struct dpaa2_fd *fd) 601 471 { 602 - struct qbman_eq_desc *p; 603 - u32 eqar = qbman_read_register(s, QBMAN_CINH_SWP_EQAR); 472 + int flags = 0; 473 + int ret = qbman_swp_enqueue_multiple_direct(s, d, fd, &flags, 1); 604 474 605 - if (!EQAR_SUCCESS(eqar)) 606 - return -EBUSY; 475 + if (ret >= 0) 476 + ret = 0; 477 + else 478 + ret = -EBUSY; 479 + return ret; 480 + } 607 481 608 - p = qbman_get_cmd(s, QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar))); 609 - memcpy(&p->dca, &d->dca, 31); 610 - memcpy(&p->fd, fd, sizeof(*fd)); 482 + /** 483 + * qbman_swp_enqueue_mem_back() - Issue an enqueue command 484 + * @s: the software portal used for enqueue 485 + * @d: the enqueue descriptor 486 + * @fd: the frame descriptor to be enqueued 487 + * 488 + * Please note that 'fd' should only be NULL if the "action" of the 489 + * descriptor is "orp_hole" or "orp_nesn". 490 + * 491 + * Return 0 for successful enqueue, -EBUSY if the EQCR is not ready. 492 + */ 493 + static 494 + int qbman_swp_enqueue_mem_back(struct qbman_swp *s, 495 + const struct qbman_eq_desc *d, 496 + const struct dpaa2_fd *fd) 497 + { 498 + int flags = 0; 499 + int ret = qbman_swp_enqueue_multiple_mem_back(s, d, fd, &flags, 1); 611 500 612 - if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) { 613 - /* Set the verb byte, have to substitute in the valid-bit */ 614 - dma_wmb(); 615 - p->verb = d->verb | EQAR_VB(eqar); 616 - } else { 617 - p->verb = d->verb | EQAR_VB(eqar); 618 - dma_wmb(); 619 - qbman_write_eqcr_am_rt_register(s, EQAR_IDX(eqar)); 501 + if (ret >= 0) 502 + ret = 0; 503 + else 504 + ret = -EBUSY; 505 + return ret; 506 + } 507 + 508 + /** 509 + * qbman_swp_enqueue_multiple_direct() - Issue a multi enqueue command 510 + * using one enqueue descriptor 511 + * @s: the software portal used for enqueue 512 + * @d: the enqueue descriptor 513 + * @fd: table pointer of frame descriptor table to be enqueued 514 + * @flags: table pointer of QBMAN_ENQUEUE_FLAG_DCA flags, not used if NULL 515 + * @num_frames: number of fd to be enqueued 516 + * 517 + * Return the number of fd enqueued, or a negative error number. 518 + */ 519 + static 520 + int qbman_swp_enqueue_multiple_direct(struct qbman_swp *s, 521 + const struct qbman_eq_desc *d, 522 + const struct dpaa2_fd *fd, 523 + uint32_t *flags, 524 + int num_frames) 525 + { 526 + uint32_t *p = NULL; 527 + const uint32_t *cl = (uint32_t *)d; 528 + uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask; 529 + int i, num_enqueued = 0; 530 + uint64_t addr_cena; 531 + 532 + spin_lock(&s->access_spinlock); 533 + half_mask = (s->eqcr.pi_ci_mask>>1); 534 + full_mask = s->eqcr.pi_ci_mask; 535 + 536 + if (!s->eqcr.available) { 537 + eqcr_ci = s->eqcr.ci; 538 + p = s->addr_cena + QBMAN_CENA_SWP_EQCR_CI; 539 + s->eqcr.ci = qbman_read_register(s, QBMAN_CINH_SWP_EQCR_CI); 540 + 541 + s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, 542 + eqcr_ci, s->eqcr.ci); 543 + if (!s->eqcr.available) { 544 + spin_unlock(&s->access_spinlock); 545 + return 0; 546 + } 620 547 } 621 548 622 - return 0; 549 + eqcr_pi = s->eqcr.pi; 550 + num_enqueued = (s->eqcr.available < num_frames) ? 551 + s->eqcr.available : num_frames; 552 + s->eqcr.available -= num_enqueued; 553 + /* Fill in the EQCR ring */ 554 + for (i = 0; i < num_enqueued; i++) { 555 + p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 556 + /* Skip copying the verb */ 557 + memcpy(&p[1], &cl[1], EQ_DESC_SIZE_WITHOUT_FD - 1); 558 + memcpy(&p[EQ_DESC_SIZE_FD_START/sizeof(uint32_t)], 559 + &fd[i], sizeof(*fd)); 560 + eqcr_pi++; 561 + } 562 + 563 + dma_wmb(); 564 + 565 + /* Set the verb byte, have to substitute in the valid-bit */ 566 + eqcr_pi = s->eqcr.pi; 567 + for (i = 0; i < num_enqueued; i++) { 568 + p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 569 + p[0] = cl[0] | s->eqcr.pi_vb; 570 + if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) { 571 + struct qbman_eq_desc *d = (struct qbman_eq_desc *)p; 572 + 573 + d->dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) | 574 + ((flags[i]) & QBMAN_EQCR_DCA_IDXMASK); 575 + } 576 + eqcr_pi++; 577 + if (!(eqcr_pi & half_mask)) 578 + s->eqcr.pi_vb ^= QB_VALID_BIT; 579 + } 580 + 581 + /* Flush all the cacheline without load/store in between */ 582 + eqcr_pi = s->eqcr.pi; 583 + addr_cena = (size_t)s->addr_cena; 584 + for (i = 0; i < num_enqueued; i++) 585 + eqcr_pi++; 586 + s->eqcr.pi = eqcr_pi & full_mask; 587 + spin_unlock(&s->access_spinlock); 588 + 589 + return num_enqueued; 590 + } 591 + 592 + /** 593 + * qbman_swp_enqueue_multiple_mem_back() - Issue a multi enqueue command 594 + * using one enqueue descriptor 595 + * @s: the software portal used for enqueue 596 + * @d: the enqueue descriptor 597 + * @fd: table pointer of frame descriptor table to be enqueued 598 + * @flags: table pointer of QBMAN_ENQUEUE_FLAG_DCA flags, not used if NULL 599 + * @num_frames: number of fd to be enqueued 600 + * 601 + * Return the number of fd enqueued, or a negative error number. 602 + */ 603 + static 604 + int qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s, 605 + const struct qbman_eq_desc *d, 606 + const struct dpaa2_fd *fd, 607 + uint32_t *flags, 608 + int num_frames) 609 + { 610 + uint32_t *p = NULL; 611 + const uint32_t *cl = (uint32_t *)(d); 612 + uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask; 613 + int i, num_enqueued = 0; 614 + unsigned long irq_flags; 615 + 616 + spin_lock(&s->access_spinlock); 617 + local_irq_save(irq_flags); 618 + 619 + half_mask = (s->eqcr.pi_ci_mask>>1); 620 + full_mask = s->eqcr.pi_ci_mask; 621 + if (!s->eqcr.available) { 622 + eqcr_ci = s->eqcr.ci; 623 + p = s->addr_cena + QBMAN_CENA_SWP_EQCR_CI_MEMBACK; 624 + s->eqcr.ci = __raw_readl(p) & full_mask; 625 + s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, 626 + eqcr_ci, s->eqcr.ci); 627 + if (!s->eqcr.available) { 628 + local_irq_restore(irq_flags); 629 + spin_unlock(&s->access_spinlock); 630 + return 0; 631 + } 632 + } 633 + 634 + eqcr_pi = s->eqcr.pi; 635 + num_enqueued = (s->eqcr.available < num_frames) ? 636 + s->eqcr.available : num_frames; 637 + s->eqcr.available -= num_enqueued; 638 + /* Fill in the EQCR ring */ 639 + for (i = 0; i < num_enqueued; i++) { 640 + p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 641 + /* Skip copying the verb */ 642 + memcpy(&p[1], &cl[1], EQ_DESC_SIZE_WITHOUT_FD - 1); 643 + memcpy(&p[EQ_DESC_SIZE_FD_START/sizeof(uint32_t)], 644 + &fd[i], sizeof(*fd)); 645 + eqcr_pi++; 646 + } 647 + 648 + /* Set the verb byte, have to substitute in the valid-bit */ 649 + eqcr_pi = s->eqcr.pi; 650 + for (i = 0; i < num_enqueued; i++) { 651 + p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 652 + p[0] = cl[0] | s->eqcr.pi_vb; 653 + if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) { 654 + struct qbman_eq_desc *d = (struct qbman_eq_desc *)p; 655 + 656 + d->dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) | 657 + ((flags[i]) & QBMAN_EQCR_DCA_IDXMASK); 658 + } 659 + eqcr_pi++; 660 + if (!(eqcr_pi & half_mask)) 661 + s->eqcr.pi_vb ^= QB_VALID_BIT; 662 + } 663 + s->eqcr.pi = eqcr_pi & full_mask; 664 + 665 + dma_wmb(); 666 + qbman_write_register(s, QBMAN_CINH_SWP_EQCR_PI, 667 + (QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb); 668 + local_irq_restore(irq_flags); 669 + spin_unlock(&s->access_spinlock); 670 + 671 + return num_enqueued; 672 + } 673 + 674 + /** 675 + * qbman_swp_enqueue_multiple_desc_direct() - Issue a multi enqueue command 676 + * using multiple enqueue descriptor 677 + * @s: the software portal used for enqueue 678 + * @d: table of minimal enqueue descriptor 679 + * @fd: table pointer of frame descriptor table to be enqueued 680 + * @num_frames: number of fd to be enqueued 681 + * 682 + * Return the number of fd enqueued, or a negative error number. 683 + */ 684 + static 685 + int qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp *s, 686 + const struct qbman_eq_desc *d, 687 + const struct dpaa2_fd *fd, 688 + int num_frames) 689 + { 690 + uint32_t *p; 691 + const uint32_t *cl; 692 + uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask; 693 + int i, num_enqueued = 0; 694 + uint64_t addr_cena; 695 + 696 + half_mask = (s->eqcr.pi_ci_mask>>1); 697 + full_mask = s->eqcr.pi_ci_mask; 698 + if (!s->eqcr.available) { 699 + eqcr_ci = s->eqcr.ci; 700 + p = s->addr_cena + QBMAN_CENA_SWP_EQCR_CI; 701 + s->eqcr.ci = qbman_read_register(s, QBMAN_CINH_SWP_EQCR_CI); 702 + s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, 703 + eqcr_ci, s->eqcr.ci); 704 + if (!s->eqcr.available) 705 + return 0; 706 + } 707 + 708 + eqcr_pi = s->eqcr.pi; 709 + num_enqueued = (s->eqcr.available < num_frames) ? 710 + s->eqcr.available : num_frames; 711 + s->eqcr.available -= num_enqueued; 712 + /* Fill in the EQCR ring */ 713 + for (i = 0; i < num_enqueued; i++) { 714 + p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 715 + cl = (uint32_t *)(&d[i]); 716 + /* Skip copying the verb */ 717 + memcpy(&p[1], &cl[1], EQ_DESC_SIZE_WITHOUT_FD - 1); 718 + memcpy(&p[EQ_DESC_SIZE_FD_START/sizeof(uint32_t)], 719 + &fd[i], sizeof(*fd)); 720 + eqcr_pi++; 721 + } 722 + 723 + dma_wmb(); 724 + 725 + /* Set the verb byte, have to substitute in the valid-bit */ 726 + eqcr_pi = s->eqcr.pi; 727 + for (i = 0; i < num_enqueued; i++) { 728 + p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 729 + cl = (uint32_t *)(&d[i]); 730 + p[0] = cl[0] | s->eqcr.pi_vb; 731 + eqcr_pi++; 732 + if (!(eqcr_pi & half_mask)) 733 + s->eqcr.pi_vb ^= QB_VALID_BIT; 734 + } 735 + 736 + /* Flush all the cacheline without load/store in between */ 737 + eqcr_pi = s->eqcr.pi; 738 + addr_cena = (uint64_t)s->addr_cena; 739 + for (i = 0; i < num_enqueued; i++) 740 + eqcr_pi++; 741 + s->eqcr.pi = eqcr_pi & full_mask; 742 + 743 + return num_enqueued; 744 + } 745 + 746 + /** 747 + * qbman_swp_enqueue_multiple_desc_mem_back() - Issue a multi enqueue command 748 + * using multiple enqueue descriptor 749 + * @s: the software portal used for enqueue 750 + * @d: table of minimal enqueue descriptor 751 + * @fd: table pointer of frame descriptor table to be enqueued 752 + * @num_frames: number of fd to be enqueued 753 + * 754 + * Return the number of fd enqueued, or a negative error number. 755 + */ 756 + static 757 + int qbman_swp_enqueue_multiple_desc_mem_back(struct qbman_swp *s, 758 + const struct qbman_eq_desc *d, 759 + const struct dpaa2_fd *fd, 760 + int num_frames) 761 + { 762 + uint32_t *p; 763 + const uint32_t *cl; 764 + uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask; 765 + int i, num_enqueued = 0; 766 + 767 + half_mask = (s->eqcr.pi_ci_mask>>1); 768 + full_mask = s->eqcr.pi_ci_mask; 769 + if (!s->eqcr.available) { 770 + eqcr_ci = s->eqcr.ci; 771 + p = s->addr_cena + QBMAN_CENA_SWP_EQCR_CI_MEMBACK; 772 + s->eqcr.ci = __raw_readl(p) & full_mask; 773 + s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, 774 + eqcr_ci, s->eqcr.ci); 775 + if (!s->eqcr.available) 776 + return 0; 777 + } 778 + 779 + eqcr_pi = s->eqcr.pi; 780 + num_enqueued = (s->eqcr.available < num_frames) ? 781 + s->eqcr.available : num_frames; 782 + s->eqcr.available -= num_enqueued; 783 + /* Fill in the EQCR ring */ 784 + for (i = 0; i < num_enqueued; i++) { 785 + p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 786 + cl = (uint32_t *)(&d[i]); 787 + /* Skip copying the verb */ 788 + memcpy(&p[1], &cl[1], EQ_DESC_SIZE_WITHOUT_FD - 1); 789 + memcpy(&p[EQ_DESC_SIZE_FD_START/sizeof(uint32_t)], 790 + &fd[i], sizeof(*fd)); 791 + eqcr_pi++; 792 + } 793 + 794 + /* Set the verb byte, have to substitute in the valid-bit */ 795 + eqcr_pi = s->eqcr.pi; 796 + for (i = 0; i < num_enqueued; i++) { 797 + p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); 798 + cl = (uint32_t *)(&d[i]); 799 + p[0] = cl[0] | s->eqcr.pi_vb; 800 + eqcr_pi++; 801 + if (!(eqcr_pi & half_mask)) 802 + s->eqcr.pi_vb ^= QB_VALID_BIT; 803 + } 804 + 805 + s->eqcr.pi = eqcr_pi & full_mask; 806 + 807 + dma_wmb(); 808 + qbman_write_register(s, QBMAN_CINH_SWP_EQCR_PI, 809 + (QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb); 810 + 811 + return num_enqueued; 623 812 } 624 813 625 814 /* Static (push) dequeue */ ··· 1098 645 } 1099 646 1100 647 /** 1101 - * qbman_swp_pull() - Issue the pull dequeue command 648 + * qbman_swp_pull_direct() - Issue the pull dequeue command 1102 649 * @s: the software portal object 1103 650 * @d: the software portal descriptor which has been configured with 1104 651 * the set of qbman_pull_desc_set_*() calls ··· 1106 653 * Return 0 for success, and -EBUSY if the software portal is not ready 1107 654 * to do pull dequeue. 1108 655 */ 1109 - int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d) 656 + static 657 + int qbman_swp_pull_direct(struct qbman_swp *s, struct qbman_pull_desc *d) 658 + { 659 + struct qbman_pull_desc *p; 660 + 661 + if (!atomic_dec_and_test(&s->vdq.available)) { 662 + atomic_inc(&s->vdq.available); 663 + return -EBUSY; 664 + } 665 + s->vdq.storage = (void *)(uintptr_t)d->rsp_addr_virt; 666 + if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) 667 + p = qbman_get_cmd(s, QBMAN_CENA_SWP_VDQCR); 668 + else 669 + p = qbman_get_cmd(s, QBMAN_CENA_SWP_VDQCR_MEM); 670 + p->numf = d->numf; 671 + p->tok = QMAN_DQ_TOKEN_VALID; 672 + p->dq_src = d->dq_src; 673 + p->rsp_addr = d->rsp_addr; 674 + p->rsp_addr_virt = d->rsp_addr_virt; 675 + dma_wmb(); 676 + /* Set the verb byte, have to substitute in the valid-bit */ 677 + p->verb = d->verb | s->vdq.valid_bit; 678 + s->vdq.valid_bit ^= QB_VALID_BIT; 679 + 680 + return 0; 681 + } 682 + 683 + /** 684 + * qbman_swp_pull_mem_back() - Issue the pull dequeue command 685 + * @s: the software portal object 686 + * @d: the software portal descriptor which has been configured with 687 + * the set of qbman_pull_desc_set_*() calls 688 + * 689 + * Return 0 for success, and -EBUSY if the software portal is not ready 690 + * to do pull dequeue. 691 + */ 692 + static 693 + int qbman_swp_pull_mem_back(struct qbman_swp *s, struct qbman_pull_desc *d) 1110 694 { 1111 695 struct qbman_pull_desc *p; 1112 696 ··· 1162 672 p->rsp_addr = d->rsp_addr; 1163 673 p->rsp_addr_virt = d->rsp_addr_virt; 1164 674 1165 - if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) { 1166 - dma_wmb(); 1167 - /* Set the verb byte, have to substitute in the valid-bit */ 1168 - p->verb = d->verb | s->vdq.valid_bit; 1169 - s->vdq.valid_bit ^= QB_VALID_BIT; 1170 - } else { 1171 - p->verb = d->verb | s->vdq.valid_bit; 1172 - s->vdq.valid_bit ^= QB_VALID_BIT; 1173 - dma_wmb(); 1174 - qbman_write_register(s, QBMAN_CINH_SWP_VDQCR_RT, QMAN_RT_MODE); 1175 - } 675 + /* Set the verb byte, have to substitute in the valid-bit */ 676 + p->verb = d->verb | s->vdq.valid_bit; 677 + s->vdq.valid_bit ^= QB_VALID_BIT; 678 + dma_wmb(); 679 + qbman_write_register(s, QBMAN_CINH_SWP_VDQCR_RT, QMAN_RT_MODE); 1176 680 1177 681 return 0; 1178 682 } ··· 1174 690 #define QMAN_DQRR_PI_MASK 0xf 1175 691 1176 692 /** 1177 - * qbman_swp_dqrr_next() - Get an valid DQRR entry 693 + * qbman_swp_dqrr_next_direct() - Get an valid DQRR entry 1178 694 * @s: the software portal object 1179 695 * 1180 696 * Return NULL if there are no unconsumed DQRR entries. Return a DQRR entry 1181 697 * only once, so repeated calls can return a sequence of DQRR entries, without 1182 698 * requiring they be consumed immediately or in any particular order. 1183 699 */ 1184 - const struct dpaa2_dq *qbman_swp_dqrr_next(struct qbman_swp *s) 700 + const struct dpaa2_dq *qbman_swp_dqrr_next_direct(struct qbman_swp *s) 1185 701 { 1186 702 u32 verb; 1187 703 u32 response_verb; ··· 1224 740 QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx))); 1225 741 } 1226 742 1227 - if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) 1228 - p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)); 1229 - else 1230 - p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR_MEM(s->dqrr.next_idx)); 743 + p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)); 744 + verb = p->dq.verb; 745 + 746 + /* 747 + * If the valid-bit isn't of the expected polarity, nothing there. Note, 748 + * in the DQRR reset bug workaround, we shouldn't need to skip these 749 + * check, because we've already determined that a new entry is available 750 + * and we've invalidated the cacheline before reading it, so the 751 + * valid-bit behaviour is repaired and should tell us what we already 752 + * knew from reading PI. 753 + */ 754 + if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit) { 755 + prefetch(qbman_get_cmd(s, 756 + QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx))); 757 + return NULL; 758 + } 759 + /* 760 + * There's something there. Move "next_idx" attention to the next ring 761 + * entry (and prefetch it) before returning what we found. 762 + */ 763 + s->dqrr.next_idx++; 764 + s->dqrr.next_idx &= s->dqrr.dqrr_size - 1; /* Wrap around */ 765 + if (!s->dqrr.next_idx) 766 + s->dqrr.valid_bit ^= QB_VALID_BIT; 767 + 768 + /* 769 + * If this is the final response to a volatile dequeue command 770 + * indicate that the vdq is available 771 + */ 772 + flags = p->dq.stat; 773 + response_verb = verb & QBMAN_RESULT_MASK; 774 + if ((response_verb == QBMAN_RESULT_DQ) && 775 + (flags & DPAA2_DQ_STAT_VOLATILE) && 776 + (flags & DPAA2_DQ_STAT_EXPIRED)) 777 + atomic_inc(&s->vdq.available); 778 + 779 + prefetch(qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx))); 780 + 781 + return p; 782 + } 783 + 784 + /** 785 + * qbman_swp_dqrr_next_mem_back() - Get an valid DQRR entry 786 + * @s: the software portal object 787 + * 788 + * Return NULL if there are no unconsumed DQRR entries. Return a DQRR entry 789 + * only once, so repeated calls can return a sequence of DQRR entries, without 790 + * requiring they be consumed immediately or in any particular order. 791 + */ 792 + const struct dpaa2_dq *qbman_swp_dqrr_next_mem_back(struct qbman_swp *s) 793 + { 794 + u32 verb; 795 + u32 response_verb; 796 + u32 flags; 797 + struct dpaa2_dq *p; 798 + 799 + /* Before using valid-bit to detect if something is there, we have to 800 + * handle the case of the DQRR reset bug... 801 + */ 802 + if (unlikely(s->dqrr.reset_bug)) { 803 + /* 804 + * We pick up new entries by cache-inhibited producer index, 805 + * which means that a non-coherent mapping would require us to 806 + * invalidate and read *only* once that PI has indicated that 807 + * there's an entry here. The first trip around the DQRR ring 808 + * will be much less efficient than all subsequent trips around 809 + * it... 810 + */ 811 + u8 pi = qbman_read_register(s, QBMAN_CINH_SWP_DQPI) & 812 + QMAN_DQRR_PI_MASK; 813 + 814 + /* there are new entries if pi != next_idx */ 815 + if (pi == s->dqrr.next_idx) 816 + return NULL; 817 + 818 + /* 819 + * if next_idx is/was the last ring index, and 'pi' is 820 + * different, we can disable the workaround as all the ring 821 + * entries have now been DMA'd to so valid-bit checking is 822 + * repaired. Note: this logic needs to be based on next_idx 823 + * (which increments one at a time), rather than on pi (which 824 + * can burst and wrap-around between our snapshots of it). 825 + */ 826 + if (s->dqrr.next_idx == (s->dqrr.dqrr_size - 1)) { 827 + pr_debug("next_idx=%d, pi=%d, clear reset bug\n", 828 + s->dqrr.next_idx, pi); 829 + s->dqrr.reset_bug = 0; 830 + } 831 + prefetch(qbman_get_cmd(s, 832 + QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx))); 833 + } 834 + 835 + p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR_MEM(s->dqrr.next_idx)); 1231 836 verb = p->dq.verb; 1232 837 1233 838 /* ··· 1445 872 #define RAR_SUCCESS(rar) ((rar) & 0x100) 1446 873 1447 874 /** 1448 - * qbman_swp_release() - Issue a buffer release command 875 + * qbman_swp_release_direct() - Issue a buffer release command 1449 876 * @s: the software portal object 1450 877 * @d: the release descriptor 1451 878 * @buffers: a pointer pointing to the buffer address to be released ··· 1453 880 * 1454 881 * Return 0 for success, -EBUSY if the release command ring is not ready. 1455 882 */ 1456 - int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d, 1457 - const u64 *buffers, unsigned int num_buffers) 883 + int qbman_swp_release_direct(struct qbman_swp *s, 884 + const struct qbman_release_desc *d, 885 + const u64 *buffers, unsigned int num_buffers) 1458 886 { 1459 887 int i; 1460 888 struct qbman_release_desc *p; ··· 1469 895 return -EBUSY; 1470 896 1471 897 /* Start the release command */ 1472 - if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) 1473 - p = qbman_get_cmd(s, QBMAN_CENA_SWP_RCR(RAR_IDX(rar))); 1474 - else 1475 - p = qbman_get_cmd(s, QBMAN_CENA_SWP_RCR_MEM(RAR_IDX(rar))); 898 + p = qbman_get_cmd(s, QBMAN_CENA_SWP_RCR(RAR_IDX(rar))); 899 + 1476 900 /* Copy the caller's buffer pointers to the command */ 1477 901 for (i = 0; i < num_buffers; i++) 1478 902 p->buf[i] = cpu_to_le64(buffers[i]); 1479 903 p->bpid = d->bpid; 1480 904 1481 - if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) { 1482 - /* 1483 - * Set the verb byte, have to substitute in the valid-bit 1484 - * and the number of buffers. 1485 - */ 1486 - dma_wmb(); 1487 - p->verb = d->verb | RAR_VB(rar) | num_buffers; 1488 - } else { 1489 - p->verb = d->verb | RAR_VB(rar) | num_buffers; 1490 - dma_wmb(); 1491 - qbman_write_register(s, QBMAN_CINH_SWP_RCR_AM_RT + 1492 - RAR_IDX(rar) * 4, QMAN_RT_MODE); 1493 - } 905 + /* 906 + * Set the verb byte, have to substitute in the valid-bit 907 + * and the number of buffers. 908 + */ 909 + dma_wmb(); 910 + p->verb = d->verb | RAR_VB(rar) | num_buffers; 911 + 912 + return 0; 913 + } 914 + 915 + /** 916 + * qbman_swp_release_mem_back() - Issue a buffer release command 917 + * @s: the software portal object 918 + * @d: the release descriptor 919 + * @buffers: a pointer pointing to the buffer address to be released 920 + * @num_buffers: number of buffers to be released, must be less than 8 921 + * 922 + * Return 0 for success, -EBUSY if the release command ring is not ready. 923 + */ 924 + int qbman_swp_release_mem_back(struct qbman_swp *s, 925 + const struct qbman_release_desc *d, 926 + const u64 *buffers, unsigned int num_buffers) 927 + { 928 + int i; 929 + struct qbman_release_desc *p; 930 + u32 rar; 931 + 932 + if (!num_buffers || (num_buffers > 7)) 933 + return -EINVAL; 934 + 935 + rar = qbman_read_register(s, QBMAN_CINH_SWP_RAR); 936 + if (!RAR_SUCCESS(rar)) 937 + return -EBUSY; 938 + 939 + /* Start the release command */ 940 + p = qbman_get_cmd(s, QBMAN_CENA_SWP_RCR_MEM(RAR_IDX(rar))); 941 + 942 + /* Copy the caller's buffer pointers to the command */ 943 + for (i = 0; i < num_buffers; i++) 944 + p->buf[i] = cpu_to_le64(buffers[i]); 945 + p->bpid = d->bpid; 946 + 947 + p->verb = d->verb | RAR_VB(rar) | num_buffers; 948 + dma_wmb(); 949 + qbman_write_register(s, QBMAN_CINH_SWP_RCR_AM_RT + 950 + RAR_IDX(rar) * 4, QMAN_RT_MODE); 1494 951 1495 952 return 0; 1496 953 }
+151 -7
drivers/soc/fsl/dpio/qbman-portal.h
··· 9 9 10 10 #include <soc/fsl/dpaa2-fd.h> 11 11 12 + #define QMAN_REV_4000 0x04000000 13 + #define QMAN_REV_4100 0x04010000 14 + #define QMAN_REV_4101 0x04010001 15 + #define QMAN_REV_5000 0x05000000 16 + 17 + #define QMAN_REV_MASK 0xffff0000 18 + 12 19 struct dpaa2_dq; 13 20 struct qbman_swp; 14 21 ··· 88 81 u8 wae; 89 82 u8 rspid; 90 83 __le64 rsp_addr; 84 + }; 85 + 86 + struct qbman_eq_desc_with_fd { 87 + struct qbman_eq_desc desc; 91 88 u8 fd[32]; 92 89 }; 93 90 ··· 143 132 u8 dqrr_size; 144 133 int reset_bug; /* indicates dqrr reset workaround is needed */ 145 134 } dqrr; 135 + 136 + struct { 137 + u32 pi; 138 + u32 pi_vb; 139 + u32 pi_ring_size; 140 + u32 pi_ci_mask; 141 + u32 ci; 142 + int available; 143 + u32 pend; 144 + u32 no_pfdr; 145 + } eqcr; 146 + 147 + spinlock_t access_spinlock; 146 148 }; 147 149 150 + /* Function pointers */ 151 + extern 152 + int (*qbman_swp_enqueue_ptr)(struct qbman_swp *s, 153 + const struct qbman_eq_desc *d, 154 + const struct dpaa2_fd *fd); 155 + extern 156 + int (*qbman_swp_enqueue_multiple_ptr)(struct qbman_swp *s, 157 + const struct qbman_eq_desc *d, 158 + const struct dpaa2_fd *fd, 159 + uint32_t *flags, 160 + int num_frames); 161 + extern 162 + int (*qbman_swp_enqueue_multiple_desc_ptr)(struct qbman_swp *s, 163 + const struct qbman_eq_desc *d, 164 + const struct dpaa2_fd *fd, 165 + int num_frames); 166 + extern 167 + int (*qbman_swp_pull_ptr)(struct qbman_swp *s, struct qbman_pull_desc *d); 168 + extern 169 + const struct dpaa2_dq *(*qbman_swp_dqrr_next_ptr)(struct qbman_swp *s); 170 + extern 171 + int (*qbman_swp_release_ptr)(struct qbman_swp *s, 172 + const struct qbman_release_desc *d, 173 + const u64 *buffers, 174 + unsigned int num_buffers); 175 + 176 + /* Functions */ 148 177 struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d); 149 178 void qbman_swp_finish(struct qbman_swp *p); 150 179 u32 qbman_swp_interrupt_read_status(struct qbman_swp *p); ··· 209 158 void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, u32 chid, 210 159 enum qbman_pull_type_e dct); 211 160 212 - int qbman_swp_pull(struct qbman_swp *p, struct qbman_pull_desc *d); 213 - 214 - const struct dpaa2_dq *qbman_swp_dqrr_next(struct qbman_swp *s); 215 161 void qbman_swp_dqrr_consume(struct qbman_swp *s, const struct dpaa2_dq *dq); 216 162 217 163 int qbman_result_has_new_result(struct qbman_swp *p, const struct dpaa2_dq *dq); ··· 220 172 void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, u32 qdid, 221 173 u32 qd_bin, u32 qd_prio); 222 174 223 - int qbman_swp_enqueue(struct qbman_swp *p, const struct qbman_eq_desc *d, 224 - const struct dpaa2_fd *fd); 225 175 226 176 void qbman_release_desc_clear(struct qbman_release_desc *d); 227 177 void qbman_release_desc_set_bpid(struct qbman_release_desc *d, u16 bpid); 228 178 void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable); 229 179 230 - int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d, 231 - const u64 *buffers, unsigned int num_buffers); 232 180 int qbman_swp_acquire(struct qbman_swp *s, u16 bpid, u64 *buffers, 233 181 unsigned int num_buffers); 234 182 int qbman_swp_alt_fq_state(struct qbman_swp *s, u32 fqid, ··· 236 192 void *qbman_swp_mc_start(struct qbman_swp *p); 237 193 void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, u8 cmd_verb); 238 194 void *qbman_swp_mc_result(struct qbman_swp *p); 195 + 196 + /** 197 + * qbman_swp_enqueue() - Issue an enqueue command 198 + * @s: the software portal used for enqueue 199 + * @d: the enqueue descriptor 200 + * @fd: the frame descriptor to be enqueued 201 + * 202 + * Return 0 for successful enqueue, -EBUSY if the EQCR is not ready. 203 + */ 204 + static inline int 205 + qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d, 206 + const struct dpaa2_fd *fd) 207 + { 208 + return qbman_swp_enqueue_ptr(s, d, fd); 209 + } 210 + 211 + /** 212 + * qbman_swp_enqueue_multiple() - Issue a multi enqueue command 213 + * using one enqueue descriptor 214 + * @s: the software portal used for enqueue 215 + * @d: the enqueue descriptor 216 + * @fd: table pointer of frame descriptor table to be enqueued 217 + * @flags: table pointer of QBMAN_ENQUEUE_FLAG_DCA flags, not used if NULL 218 + * @num_frames: number of fd to be enqueued 219 + * 220 + * Return the number of fd enqueued, or a negative error number. 221 + */ 222 + static inline int 223 + qbman_swp_enqueue_multiple(struct qbman_swp *s, 224 + const struct qbman_eq_desc *d, 225 + const struct dpaa2_fd *fd, 226 + uint32_t *flags, 227 + int num_frames) 228 + { 229 + return qbman_swp_enqueue_multiple_ptr(s, d, fd, flags, num_frames); 230 + } 231 + 232 + /** 233 + * qbman_swp_enqueue_multiple_desc() - Issue a multi enqueue command 234 + * using multiple enqueue descriptor 235 + * @s: the software portal used for enqueue 236 + * @d: table of minimal enqueue descriptor 237 + * @fd: table pointer of frame descriptor table to be enqueued 238 + * @num_frames: number of fd to be enqueued 239 + * 240 + * Return the number of fd enqueued, or a negative error number. 241 + */ 242 + static inline int 243 + qbman_swp_enqueue_multiple_desc(struct qbman_swp *s, 244 + const struct qbman_eq_desc *d, 245 + const struct dpaa2_fd *fd, 246 + int num_frames) 247 + { 248 + return qbman_swp_enqueue_multiple_desc_ptr(s, d, fd, num_frames); 249 + } 239 250 240 251 /** 241 252 * qbman_result_is_DQ() - check if the dequeue result is a dequeue response ··· 602 503 struct qbman_bp_query_rslt *r); 603 504 604 505 u32 qbman_bp_info_num_free_bufs(struct qbman_bp_query_rslt *a); 506 + 507 + /** 508 + * qbman_swp_release() - Issue a buffer release command 509 + * @s: the software portal object 510 + * @d: the release descriptor 511 + * @buffers: a pointer pointing to the buffer address to be released 512 + * @num_buffers: number of buffers to be released, must be less than 8 513 + * 514 + * Return 0 for success, -EBUSY if the release command ring is not ready. 515 + */ 516 + static inline int qbman_swp_release(struct qbman_swp *s, 517 + const struct qbman_release_desc *d, 518 + const u64 *buffers, 519 + unsigned int num_buffers) 520 + { 521 + return qbman_swp_release_ptr(s, d, buffers, num_buffers); 522 + } 523 + 524 + /** 525 + * qbman_swp_pull() - Issue the pull dequeue command 526 + * @s: the software portal object 527 + * @d: the software portal descriptor which has been configured with 528 + * the set of qbman_pull_desc_set_*() calls 529 + * 530 + * Return 0 for success, and -EBUSY if the software portal is not ready 531 + * to do pull dequeue. 532 + */ 533 + static inline int qbman_swp_pull(struct qbman_swp *s, 534 + struct qbman_pull_desc *d) 535 + { 536 + return qbman_swp_pull_ptr(s, d); 537 + } 538 + 539 + /** 540 + * qbman_swp_dqrr_next() - Get an valid DQRR entry 541 + * @s: the software portal object 542 + * 543 + * Return NULL if there are no unconsumed DQRR entries. Return a DQRR entry 544 + * only once, so repeated calls can return a sequence of DQRR entries, without 545 + * requiring they be consumed immediately or in any particular order. 546 + */ 547 + static inline const struct dpaa2_dq *qbman_swp_dqrr_next(struct qbman_swp *s) 548 + { 549 + return qbman_swp_dqrr_next_ptr(s); 550 + } 605 551 606 552 #endif /* __FSL_QBMAN_PORTAL_H */
+2 -2
drivers/soc/fsl/qe/qe.c
··· 423 423 qe_iowrite32be(be32_to_cpu(code[i]), &qe_immr->iram.idata); 424 424 425 425 /* Set I-RAM Ready Register */ 426 - qe_iowrite32be(be32_to_cpu(QE_IRAM_READY), &qe_immr->iram.iready); 426 + qe_iowrite32be(QE_IRAM_READY, &qe_immr->iram.iready); 427 427 } 428 428 429 429 /* ··· 525 525 */ 526 526 memset(&qe_firmware_info, 0, sizeof(qe_firmware_info)); 527 527 strlcpy(qe_firmware_info.id, firmware->id, sizeof(qe_firmware_info.id)); 528 - qe_firmware_info.extended_modes = firmware->extended_modes; 528 + qe_firmware_info.extended_modes = be64_to_cpu(firmware->extended_modes); 529 529 memcpy(qe_firmware_info.vtraps, firmware->vtraps, 530 530 sizeof(firmware->vtraps)); 531 531
+1 -1
drivers/soc/fsl/qe/qe_common.c
··· 46 46 { 47 47 struct device_node *np; 48 48 struct resource r; 49 - u32 zero[OF_MAX_ADDR_CELLS] = {}; 49 + __be32 zero[OF_MAX_ADDR_CELLS] = {}; 50 50 resource_size_t max = 0; 51 51 int i = 0; 52 52 int ret = 0;
+1 -1
drivers/soc/fsl/qe/qe_ic.c
··· 44 44 45 45 struct qe_ic { 46 46 /* Control registers offset */ 47 - u32 __iomem *regs; 47 + __be32 __iomem *regs; 48 48 49 49 /* The remapper for this QEIC */ 50 50 struct irq_domain *irqhost;
+1 -1
drivers/soc/fsl/qe/ucc.c
··· 632 632 { 633 633 int source; 634 634 u32 shift; 635 - struct qe_mux *qe_mux_reg; 635 + struct qe_mux __iomem *qe_mux_reg; 636 636 637 637 qe_mux_reg = &qe_immr->qmx; 638 638
+13 -20
drivers/soc/fsl/qe/ucc_slow.c
··· 72 72 73 73 void ucc_slow_enable(struct ucc_slow_private * uccs, enum comm_dir mode) 74 74 { 75 - struct ucc_slow *us_regs; 75 + struct ucc_slow __iomem *us_regs; 76 76 u32 gumr_l; 77 77 78 78 us_regs = uccs->us_regs; ··· 93 93 94 94 void ucc_slow_disable(struct ucc_slow_private * uccs, enum comm_dir mode) 95 95 { 96 - struct ucc_slow *us_regs; 96 + struct ucc_slow __iomem *us_regs; 97 97 u32 gumr_l; 98 98 99 99 us_regs = uccs->us_regs; ··· 122 122 u32 i; 123 123 struct ucc_slow __iomem *us_regs; 124 124 u32 gumr; 125 - struct qe_bd *bd; 125 + struct qe_bd __iomem *bd; 126 126 u32 id; 127 127 u32 command; 128 128 int ret = 0; ··· 168 168 return -ENOMEM; 169 169 } 170 170 171 - uccs->saved_uccm = 0; 172 - uccs->p_rx_frame = 0; 173 171 us_regs = uccs->us_regs; 174 - uccs->p_ucce = (u16 *) & (us_regs->ucce); 175 - uccs->p_uccm = (u16 *) & (us_regs->uccm); 176 - #ifdef STATISTICS 177 - uccs->rx_frames = 0; 178 - uccs->tx_frames = 0; 179 - uccs->rx_discarded = 0; 180 - #endif /* STATISTICS */ 172 + uccs->p_ucce = &us_regs->ucce; 173 + uccs->p_uccm = &us_regs->uccm; 181 174 182 175 /* Get PRAM base */ 183 176 uccs->us_pram_offset = ··· 224 231 /* clear bd buffer */ 225 232 qe_iowrite32be(0, &bd->buf); 226 233 /* set bd status and length */ 227 - qe_iowrite32be(0, (u32 *)bd); 234 + qe_iowrite32be(0, (u32 __iomem *)bd); 228 235 bd++; 229 236 } 230 237 /* for last BD set Wrap bit */ 231 238 qe_iowrite32be(0, &bd->buf); 232 - qe_iowrite32be(cpu_to_be32(T_W), (u32 *)bd); 239 + qe_iowrite32be(T_W, (u32 __iomem *)bd); 233 240 234 241 /* Init Rx bds */ 235 242 bd = uccs->rx_bd = qe_muram_addr(uccs->rx_base_offset); 236 243 for (i = 0; i < us_info->rx_bd_ring_len - 1; i++) { 237 244 /* set bd status and length */ 238 - qe_iowrite32be(0, (u32 *)bd); 245 + qe_iowrite32be(0, (u32 __iomem *)bd); 239 246 /* clear bd buffer */ 240 247 qe_iowrite32be(0, &bd->buf); 241 248 bd++; 242 249 } 243 250 /* for last BD set Wrap bit */ 244 - qe_iowrite32be(cpu_to_be32(R_W), (u32 *)bd); 251 + qe_iowrite32be(R_W, (u32 __iomem *)bd); 245 252 qe_iowrite32be(0, &bd->buf); 246 253 247 254 /* Set GUMR (For more details see the hardware spec.). */ ··· 266 273 qe_iowrite32be(gumr, &us_regs->gumr_h); 267 274 268 275 /* gumr_l */ 269 - gumr = us_info->tdcr | us_info->rdcr | us_info->tenc | us_info->renc | 270 - us_info->diag | us_info->mode; 276 + gumr = (u32)us_info->tdcr | (u32)us_info->rdcr | (u32)us_info->tenc | 277 + (u32)us_info->renc | (u32)us_info->diag | (u32)us_info->mode; 271 278 if (us_info->tci) 272 279 gumr |= UCC_SLOW_GUMR_L_TCI; 273 280 if (us_info->rinv) ··· 282 289 283 290 /* if the data is in cachable memory, the 'global' */ 284 291 /* in the function code should be set. */ 285 - uccs->us_pram->tbmr = UCC_BMR_BO_BE; 286 - uccs->us_pram->rbmr = UCC_BMR_BO_BE; 292 + qe_iowrite8(UCC_BMR_BO_BE, &uccs->us_pram->tbmr); 293 + qe_iowrite8(UCC_BMR_BO_BE, &uccs->us_pram->rbmr); 287 294 288 295 /* rbase, tbase are offsets from MURAM base */ 289 296 qe_iowrite16be(uccs->rx_base_offset, &uccs->us_pram->rbase);
+5 -1
include/soc/fsl/dpaa2-io.h
··· 1 1 /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ 2 2 /* 3 3 * Copyright 2014-2016 Freescale Semiconductor Inc. 4 - * Copyright NXP 4 + * Copyright 2017-2019 NXP 5 5 * 6 6 */ 7 7 #ifndef __FSL_DPAA2_IO_H ··· 109 109 110 110 int dpaa2_io_service_enqueue_fq(struct dpaa2_io *d, u32 fqid, 111 111 const struct dpaa2_fd *fd); 112 + int dpaa2_io_service_enqueue_multiple_fq(struct dpaa2_io *d, u32 fqid, 113 + const struct dpaa2_fd *fd, int number_of_frame); 114 + int dpaa2_io_service_enqueue_multiple_desc_fq(struct dpaa2_io *d, u32 *fqid, 115 + const struct dpaa2_fd *fd, int number_of_frame); 112 116 int dpaa2_io_service_enqueue_qd(struct dpaa2_io *d, u32 qdid, u8 prio, 113 117 u16 qdbin, const struct dpaa2_fd *fd); 114 118 int dpaa2_io_service_release(struct dpaa2_io *d, u16 bpid,
+3 -3
include/soc/fsl/qe/ucc_fast.h
··· 178 178 struct ucc_fast_private { 179 179 struct ucc_fast_info *uf_info; 180 180 struct ucc_fast __iomem *uf_regs; /* a pointer to the UCC regs. */ 181 - u32 __iomem *p_ucce; /* a pointer to the event register in memory. */ 182 - u32 __iomem *p_uccm; /* a pointer to the mask register in memory. */ 181 + __be32 __iomem *p_ucce; /* a pointer to the event register in memory. */ 182 + __be32 __iomem *p_uccm; /* a pointer to the mask register in memory. */ 183 183 #ifdef CONFIG_UGETH_TX_ON_DEMAND 184 - u16 __iomem *p_utodr; /* pointer to the transmit on demand register */ 184 + __be16 __iomem *p_utodr;/* pointer to the transmit on demand register */ 185 185 #endif 186 186 int enabled_tx; /* Whether channel is enabled for Tx (ENT) */ 187 187 int enabled_rx; /* Whether channel is enabled for Rx (ENR) */
+6 -7
include/soc/fsl/qe/ucc_slow.h
··· 184 184 struct ucc_slow_private { 185 185 struct ucc_slow_info *us_info; 186 186 struct ucc_slow __iomem *us_regs; /* Ptr to memory map of UCC regs */ 187 - struct ucc_slow_pram *us_pram; /* a pointer to the parameter RAM */ 187 + struct ucc_slow_pram __iomem *us_pram; /* a pointer to the parameter RAM */ 188 188 s32 us_pram_offset; 189 189 int enabled_tx; /* Whether channel is enabled for Tx (ENT) */ 190 190 int enabled_rx; /* Whether channel is enabled for Rx (ENR) */ ··· 196 196 and length for first BD in a frame */ 197 197 s32 tx_base_offset; /* first BD in Tx BD table offset (In MURAM) */ 198 198 s32 rx_base_offset; /* first BD in Rx BD table offset (In MURAM) */ 199 - struct qe_bd *confBd; /* next BD for confirm after Tx */ 200 - struct qe_bd *tx_bd; /* next BD for new Tx request */ 201 - struct qe_bd *rx_bd; /* next BD to collect after Rx */ 199 + struct qe_bd __iomem *confBd; /* next BD for confirm after Tx */ 200 + struct qe_bd __iomem *tx_bd; /* next BD for new Tx request */ 201 + struct qe_bd __iomem *rx_bd; /* next BD to collect after Rx */ 202 202 void *p_rx_frame; /* accumulating receive frame */ 203 - u16 *p_ucce; /* a pointer to the event register in memory. 204 - */ 205 - u16 *p_uccm; /* a pointer to the mask register in memory */ 203 + __be16 __iomem *p_ucce; /* a pointer to the event register in memory */ 204 + __be16 __iomem *p_uccm; /* a pointer to the mask register in memory */ 206 205 u16 saved_uccm; /* a saved mask for the RX Interrupt bits */ 207 206 #ifdef STATISTICS 208 207 u32 tx_frames; /* Transmitted frames counters */