1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * Copyright (C) 2014 Freescale Semiconductor 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+ 5*4882a593Smuzhiyun */ 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun #ifndef _FSL_QBMAN_BASE_H 8*4882a593Smuzhiyun #define _FSL_QBMAN_BASE_H 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun /* Descriptor for a QBMan instance on the SoC. On partitions/targets that do not 11*4882a593Smuzhiyun * control this QBMan instance, these values may simply be place-holders. The 12*4882a593Smuzhiyun * idea is simply that we be able to distinguish between them, eg. so that SWP 13*4882a593Smuzhiyun * descriptors can identify which QBMan instance they belong to. */ 14*4882a593Smuzhiyun struct qbman_block_desc { 15*4882a593Smuzhiyun void *ccsr_reg_bar; /* CCSR register map */ 16*4882a593Smuzhiyun int irq_rerr; /* Recoverable error interrupt line */ 17*4882a593Smuzhiyun int irq_nrerr; /* Non-recoverable error interrupt line */ 18*4882a593Smuzhiyun }; 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun /* Descriptor for a QBMan software portal, expressed in terms that make sense to 21*4882a593Smuzhiyun * the user context. Ie. on MC, this information is likely to be true-physical, 22*4882a593Smuzhiyun * and instantiated statically at compile-time. On GPP, this information is 23*4882a593Smuzhiyun * likely to be obtained via "discovery" over a partition's "layerscape bus" 24*4882a593Smuzhiyun * (ie. in response to a MC portal command), and would take into account any 25*4882a593Smuzhiyun * virtualisation of the GPP user's address space and/or interrupt numbering. */ 26*4882a593Smuzhiyun struct qbman_swp_desc { 27*4882a593Smuzhiyun const struct qbman_block_desc *block; /* The QBMan instance */ 28*4882a593Smuzhiyun void *cena_bar; /* Cache-enabled portal register map */ 29*4882a593Smuzhiyun void *cinh_bar; /* Cache-inhibited portal register map */ 30*4882a593Smuzhiyun }; 31*4882a593Smuzhiyun 32*4882a593Smuzhiyun /* Driver object for managing a QBMan portal */ 33*4882a593Smuzhiyun struct qbman_swp; 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun /* Place-holder for FDs, we represent it via the simplest form that we need for 36*4882a593Smuzhiyun * now. Different overlays may be needed to support different options, etc. (It 37*4882a593Smuzhiyun * is impractical to define One True Struct, because the resulting encoding 38*4882a593Smuzhiyun * routines (lots of read-modify-writes) would be worst-case performance whether 39*4882a593Smuzhiyun * or not circumstances required them.) 40*4882a593Smuzhiyun * 41*4882a593Smuzhiyun * Note, as with all data-structures exchanged between software and hardware (be 42*4882a593Smuzhiyun * they located in the portal register map or DMA'd to and from main-memory), 43*4882a593Smuzhiyun * the driver ensures that the caller of the driver API sees the data-structures 44*4882a593Smuzhiyun * in host-endianness. "struct qbman_fd" is no exception. The 32-bit words 45*4882a593Smuzhiyun * contained within this structure are represented in host-endianness, even if 46*4882a593Smuzhiyun * hardware always treats them as little-endian. As such, if any of these fields 47*4882a593Smuzhiyun * are interpreted in a binary (rather than numerical) fashion by hardware 48*4882a593Smuzhiyun * blocks (eg. accelerators), then the user should be careful. We illustrate 49*4882a593Smuzhiyun * with an example; 50*4882a593Smuzhiyun * 51*4882a593Smuzhiyun * Suppose the desired behaviour of an accelerator is controlled by the "frc" 52*4882a593Smuzhiyun * field of the FDs that are sent to it. Suppose also that the behaviour desired 53*4882a593Smuzhiyun * by the user corresponds to an "frc" value which is expressed as the literal 54*4882a593Smuzhiyun * sequence of bytes 0xfe, 0xed, 0xab, and 0xba. So "frc" should be the 32-bit 55*4882a593Smuzhiyun * value in which 0xfe is the first byte and 0xba is the last byte, and as 56*4882a593Smuzhiyun * hardware is little-endian, this amounts to a 32-bit "value" of 0xbaabedfe. If 57*4882a593Smuzhiyun * the software is little-endian also, this can simply be achieved by setting 58*4882a593Smuzhiyun * frc=0xbaabedfe. On the other hand, if software is big-endian, it should set 59*4882a593Smuzhiyun * frc=0xfeedabba! The best away of avoiding trouble with this sort of thing is 60*4882a593Smuzhiyun * to treat the 32-bit words as numerical values, in which the offset of a field 61*4882a593Smuzhiyun * from the beginning of the first byte (as required or generated by hardware) 62*4882a593Smuzhiyun * is numerically encoded by a left-shift (ie. by raising the field to a 63*4882a593Smuzhiyun * corresponding power of 2). Ie. in the current example, software could set 64*4882a593Smuzhiyun * "frc" in the following way, and it would work correctly on both little-endian 65*4882a593Smuzhiyun * and big-endian operation; 66*4882a593Smuzhiyun * fd.frc = (0xfe << 0) | (0xed << 8) | (0xab << 16) | (0xba << 24); 67*4882a593Smuzhiyun */ 68*4882a593Smuzhiyun struct qbman_fd { 69*4882a593Smuzhiyun union { 70*4882a593Smuzhiyun uint32_t words[8]; 71*4882a593Smuzhiyun struct qbman_fd_simple { 72*4882a593Smuzhiyun uint32_t addr_lo; 73*4882a593Smuzhiyun uint32_t addr_hi; 74*4882a593Smuzhiyun uint32_t len; 75*4882a593Smuzhiyun /* offset in the MS 16 bits, BPID in the LS 16 bits */ 76*4882a593Smuzhiyun uint32_t bpid_offset; 77*4882a593Smuzhiyun uint32_t frc; /* frame context */ 78*4882a593Smuzhiyun /* "err", "va", "cbmt", "asal", [...] */ 79*4882a593Smuzhiyun uint32_t ctrl; 80*4882a593Smuzhiyun /* flow context */ 81*4882a593Smuzhiyun uint32_t flc_lo; 82*4882a593Smuzhiyun uint32_t flc_hi; 83*4882a593Smuzhiyun } simple; 84*4882a593Smuzhiyun }; 85*4882a593Smuzhiyun }; 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun #endif /* !_FSL_QBMAN_BASE_H */ 88