Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2019 Red Hat Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  */
0022 #ifndef __NVIF_PUSH_H__
0023 #define __NVIF_PUSH_H__
0024 #include <nvif/mem.h>
0025 #include <nvif/printf.h>
0026 
0027 #include <nvhw/drf.h>
0028 
0029 struct nvif_push {
0030     int (*wait)(struct nvif_push *push, u32 size);
0031     void (*kick)(struct nvif_push *push);
0032 
0033     struct nvif_mem mem;
0034 
0035     u32 *bgn;
0036     u32 *cur;
0037     u32 *seg;
0038     u32 *end;
0039 };
0040 
0041 static inline __must_check int
0042 PUSH_WAIT(struct nvif_push *push, u32 size)
0043 {
0044     if (push->cur + size >= push->end) {
0045         int ret = push->wait(push, size);
0046         if (ret)
0047             return ret;
0048     }
0049 #ifdef CONFIG_NOUVEAU_DEBUG_PUSH
0050     push->seg = push->cur + size;
0051 #endif
0052     return 0;
0053 }
0054 
0055 static inline int
0056 PUSH_KICK(struct nvif_push *push)
0057 {
0058     push->kick(push);
0059     return 0;
0060 }
0061 
0062 #ifdef CONFIG_NOUVEAU_DEBUG_PUSH
0063 #define PUSH_PRINTF(p,f,a...) do {                              \
0064     struct nvif_push *_ppp = (p);                           \
0065     u32 __o = _ppp->cur - (u32 *)_ppp->mem.object.map.ptr;  \
0066     NVIF_DEBUG(&_ppp->mem.object, "%08x: "f, __o * 4, ##a); \
0067     (void)__o;                                              \
0068 } while(0)
0069 #define PUSH_ASSERT_ON(a,b) WARN((a), b)
0070 #else
0071 #define PUSH_PRINTF(p,f,a...)
0072 #define PUSH_ASSERT_ON(a, b)
0073 #endif
0074 
0075 #define PUSH_ASSERT(a,b) do {                                             \
0076     static_assert(                                                    \
0077         __builtin_choose_expr(__builtin_constant_p(a), (a), 1), b \
0078     );                                                                \
0079     PUSH_ASSERT_ON(!(a), b);                                          \
0080 } while(0)
0081 
0082 #define PUSH_DATA__(p,d,f,a...) do {                       \
0083     struct nvif_push *_p = (p);                        \
0084     u32 _d = (d);                                      \
0085     PUSH_ASSERT(_p->cur < _p->seg, "segment overrun"); \
0086     PUSH_ASSERT(_p->cur < _p->end, "pushbuf overrun"); \
0087     PUSH_PRINTF(_p, "%08x"f, _d, ##a);                 \
0088     *_p->cur++ = _d;                                   \
0089 } while(0)
0090 
0091 #define PUSH_DATA_(X,p,m,i0,i1,d,s,f,a...) PUSH_DATA__((p), (d), "-> "#m f, ##a)
0092 #define PUSH_DATA(p,d) PUSH_DATA__((p), (d), " data - %s", __func__)
0093 
0094 //XXX: error-check this against *real* pushbuffer end?
0095 #define PUSH_RSVD(p,d) do {          \
0096     struct nvif_push *__p = (p); \
0097     __p->seg++;                  \
0098     __p->end++;                  \
0099     d;                           \
0100 } while(0)
0101 
0102 #ifdef CONFIG_NOUVEAU_DEBUG_PUSH
0103 #define PUSH_DATAp(X,p,m,i,o,d,s,f,a...) do {                                     \
0104     struct nvif_push *_pp = (p);                                              \
0105     const u32 *_dd = (d);                                                     \
0106     u32 _s = (s), _i = (i?PUSH_##o##_INC);                                    \
0107     if (_s--) {                                                               \
0108         PUSH_DATA_(X, _pp, X##m, i0, i1, *_dd++, 1, "+0x%x", 0);          \
0109         while (_s--) {                                                    \
0110             PUSH_DATA_(X, _pp, X##m, i0, i1, *_dd++, 1, "+0x%x", _i); \
0111             _i += (0?PUSH_##o##_INC);                                 \
0112         }                                                                 \
0113     }                                                                         \
0114 } while(0)
0115 #else
0116 #define PUSH_DATAp(X,p,m,i,o,d,s,f,a...) do {                    \
0117     struct nvif_push *_p = (p);                              \
0118     u32 _s = (s);                                            \
0119     PUSH_ASSERT(_p->cur + _s <= _p->seg, "segment overrun"); \
0120     PUSH_ASSERT(_p->cur + _s <= _p->end, "pushbuf overrun"); \
0121     memcpy(_p->cur, (d), _s << 2);                           \
0122     _p->cur += _s;                                           \
0123 } while(0)
0124 #endif
0125 
0126 #define PUSH_1(X,f,ds,n,o,p,s,mA,dA) do {                             \
0127     PUSH_##o##_HDR((p), s, mA, (ds)+(n));                         \
0128     PUSH_##f(X, (p), X##mA, 1, o, (dA), ds, "");                  \
0129 } while(0)
0130 #define PUSH_2(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do {                  \
0131     PUSH_ASSERT((mB) - (mA) == (1?PUSH_##o##_INC), "mthd1");      \
0132     PUSH_1(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \
0133     PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                  \
0134 } while(0)
0135 #define PUSH_3(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do {                  \
0136     PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd2");      \
0137     PUSH_2(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \
0138     PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                  \
0139 } while(0)
0140 #define PUSH_4(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do {                  \
0141     PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd3");      \
0142     PUSH_3(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \
0143     PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                  \
0144 } while(0)
0145 #define PUSH_5(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do {                  \
0146     PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd4");      \
0147     PUSH_4(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \
0148     PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                  \
0149 } while(0)
0150 #define PUSH_6(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do {                  \
0151     PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd5");      \
0152     PUSH_5(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \
0153     PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                  \
0154 } while(0)
0155 #define PUSH_7(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do {                  \
0156     PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd6");      \
0157     PUSH_6(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \
0158     PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                  \
0159 } while(0)
0160 #define PUSH_8(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do {                  \
0161     PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd7");      \
0162     PUSH_7(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \
0163     PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                  \
0164 } while(0)
0165 #define PUSH_9(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do {                  \
0166     PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd8");      \
0167     PUSH_8(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \
0168     PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                  \
0169 } while(0)
0170 #define PUSH_10(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do {                 \
0171     PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd9");      \
0172     PUSH_9(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \
0173     PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                  \
0174 } while(0)
0175 
0176 #define PUSH_1D(X,o,p,s,mA,dA)                         \
0177     PUSH_1(X, DATA_, 1, 0, o, (p), s, X##mA, (dA))
0178 #define PUSH_2D(X,o,p,s,mA,dA,mB,dB)                   \
0179     PUSH_2(X, DATA_, 1, 0, o, (p), s, X##mB, (dB), \
0180                       X##mA, (dA))
0181 #define PUSH_3D(X,o,p,s,mA,dA,mB,dB,mC,dC)             \
0182     PUSH_3(X, DATA_, 1, 0, o, (p), s, X##mC, (dC), \
0183                       X##mB, (dB), \
0184                       X##mA, (dA))
0185 #define PUSH_4D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD)       \
0186     PUSH_4(X, DATA_, 1, 0, o, (p), s, X##mD, (dD), \
0187                       X##mC, (dC), \
0188                       X##mB, (dB), \
0189                       X##mA, (dA))
0190 #define PUSH_5D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE) \
0191     PUSH_5(X, DATA_, 1, 0, o, (p), s, X##mE, (dE), \
0192                       X##mD, (dD), \
0193                       X##mC, (dC), \
0194                       X##mB, (dB), \
0195                       X##mA, (dA))
0196 #define PUSH_6D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,dF) \
0197     PUSH_6(X, DATA_, 1, 0, o, (p), s, X##mF, (dF),       \
0198                       X##mE, (dE),       \
0199                       X##mD, (dD),       \
0200                       X##mC, (dC),       \
0201                       X##mB, (dB),       \
0202                       X##mA, (dA))
0203 #define PUSH_7D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,dF,mG,dG) \
0204     PUSH_7(X, DATA_, 1, 0, o, (p), s, X##mG, (dG),             \
0205                       X##mF, (dF),             \
0206                       X##mE, (dE),             \
0207                       X##mD, (dD),             \
0208                       X##mC, (dC),             \
0209                       X##mB, (dB),             \
0210                       X##mA, (dA))
0211 #define PUSH_8D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,dF,mG,dG,mH,dH) \
0212     PUSH_8(X, DATA_, 1, 0, o, (p), s, X##mH, (dH),                   \
0213                       X##mG, (dG),                   \
0214                       X##mF, (dF),                   \
0215                       X##mE, (dE),                   \
0216                       X##mD, (dD),                   \
0217                       X##mC, (dC),                   \
0218                       X##mB, (dB),                   \
0219                       X##mA, (dA))
0220 #define PUSH_9D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,dF,mG,dG,mH,dH,mI,dI) \
0221     PUSH_9(X, DATA_, 1, 0, o, (p), s, X##mI, (dI),                         \
0222                       X##mH, (dH),                         \
0223                       X##mG, (dG),                         \
0224                       X##mF, (dF),                         \
0225                       X##mE, (dE),                         \
0226                       X##mD, (dD),                         \
0227                       X##mC, (dC),                         \
0228                       X##mB, (dB),                         \
0229                       X##mA, (dA))
0230 #define PUSH_10D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,dF,mG,dG,mH,dH,mI,dI,mJ,dJ) \
0231     PUSH_10(X, DATA_, 1, 0, o, (p), s, X##mJ, (dJ),                               \
0232                        X##mI, (dI),                               \
0233                        X##mH, (dH),                               \
0234                        X##mG, (dG),                               \
0235                        X##mF, (dF),                               \
0236                        X##mE, (dE),                               \
0237                        X##mD, (dD),                               \
0238                        X##mC, (dC),                               \
0239                        X##mB, (dB),                               \
0240                        X##mA, (dA))
0241 
0242 #define PUSH_1P(X,o,p,s,mA,dp,ds)                       \
0243     PUSH_1(X, DATAp, ds, 0, o, (p), s, X##mA, (dp))
0244 #define PUSH_2P(X,o,p,s,mA,dA,mB,dp,ds)                 \
0245     PUSH_2(X, DATAp, ds, 0, o, (p), s, X##mB, (dp), \
0246                        X##mA, (dA))
0247 #define PUSH_3P(X,o,p,s,mA,dA,mB,dB,mC,dp,ds)           \
0248     PUSH_3(X, DATAp, ds, 0, o, (p), s, X##mC, (dp), \
0249                        X##mB, (dB), \
0250                        X##mA, (dA))
0251 
0252 #define PUSH_(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,IMPL,...) IMPL
0253 #define PUSH(A...) PUSH_(A, PUSH_10P, PUSH_10D,          \
0254                 PUSH_9P , PUSH_9D,           \
0255                 PUSH_8P , PUSH_8D,           \
0256                 PUSH_7P , PUSH_7D,           \
0257                 PUSH_6P , PUSH_6D,           \
0258                 PUSH_5P , PUSH_5D,           \
0259                 PUSH_4P , PUSH_4D,           \
0260                 PUSH_3P , PUSH_3D,           \
0261                 PUSH_2P , PUSH_2D,           \
0262                 PUSH_1P , PUSH_1D)(, ##A)
0263 
0264 #define PUSH_NVIM(p,c,m,d) do {             \
0265     struct nvif_push *__p = (p);        \
0266     u32 __d = (d);                      \
0267     PUSH_IMMD_HDR(__p, c, m, __d);      \
0268     __p->cur--;                         \
0269     PUSH_PRINTF(__p, "%08x-> "#m, __d); \
0270     __p->cur++;                         \
0271 } while(0)
0272 #define PUSH_NVSQ(A...) PUSH(MTHD, ##A)
0273 #define PUSH_NV1I(A...) PUSH(1INC, ##A)
0274 #define PUSH_NVNI(A...) PUSH(NINC, ##A)
0275 
0276 
0277 #define PUSH_NV_1(X,o,p,c,mA,d...) \
0278        PUSH_##o(p,c,c##_##mA,d)
0279 #define PUSH_NV_2(X,o,p,c,mA,dA,mB,d...) \
0280        PUSH_##o(p,c,c##_##mA,dA,         \
0281             c##_##mB,d)
0282 #define PUSH_NV_3(X,o,p,c,mA,dA,mB,dB,mC,d...) \
0283        PUSH_##o(p,c,c##_##mA,dA,               \
0284             c##_##mB,dB,               \
0285             c##_##mC,d)
0286 #define PUSH_NV_4(X,o,p,c,mA,dA,mB,dB,mC,dC,mD,d...) \
0287        PUSH_##o(p,c,c##_##mA,dA,                     \
0288             c##_##mB,dB,                     \
0289             c##_##mC,dC,                     \
0290             c##_##mD,d)
0291 #define PUSH_NV_5(X,o,p,c,mA,dA,mB,dB,mC,dC,mD,dD,mE,d...) \
0292        PUSH_##o(p,c,c##_##mA,dA,                           \
0293             c##_##mB,dB,                           \
0294             c##_##mC,dC,                           \
0295             c##_##mD,dD,                           \
0296             c##_##mE,d)
0297 #define PUSH_NV_6(X,o,p,c,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,d...) \
0298        PUSH_##o(p,c,c##_##mA,dA,                                 \
0299             c##_##mB,dB,                                 \
0300             c##_##mC,dC,                                 \
0301             c##_##mD,dD,                                 \
0302             c##_##mE,dE,                                 \
0303             c##_##mF,d)
0304 #define PUSH_NV_7(X,o,p,c,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,dF,mG,d...) \
0305        PUSH_##o(p,c,c##_##mA,dA,                                       \
0306             c##_##mB,dB,                                       \
0307             c##_##mC,dC,                                       \
0308             c##_##mD,dD,                                       \
0309             c##_##mE,dE,                                       \
0310             c##_##mF,dF,                                       \
0311             c##_##mG,d)
0312 #define PUSH_NV_8(X,o,p,c,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,dF,mG,dG,mH,d...) \
0313        PUSH_##o(p,c,c##_##mA,dA,                                             \
0314             c##_##mB,dB,                                             \
0315             c##_##mC,dC,                                             \
0316             c##_##mD,dD,                                             \
0317             c##_##mE,dE,                                             \
0318             c##_##mF,dF,                                             \
0319             c##_##mG,dG,                                             \
0320             c##_##mH,d)
0321 #define PUSH_NV_9(X,o,p,c,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,dF,mG,dG,mH,dH,mI,d...) \
0322        PUSH_##o(p,c,c##_##mA,dA,                                                   \
0323             c##_##mB,dB,                                                   \
0324             c##_##mC,dC,                                                   \
0325             c##_##mD,dD,                                                   \
0326             c##_##mE,dE,                                                   \
0327             c##_##mF,dF,                                                   \
0328             c##_##mG,dG,                                                   \
0329             c##_##mH,dH,                                                   \
0330             c##_##mI,d)
0331 #define PUSH_NV_10(X,o,p,c,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,dF,mG,dG,mH,dH,mI,dI,mJ,d...) \
0332        PUSH_##o(p,c,c##_##mA,dA,                                                          \
0333             c##_##mB,dB,                                                          \
0334             c##_##mC,dC,                                                          \
0335             c##_##mD,dD,                                                          \
0336             c##_##mE,dE,                                                          \
0337             c##_##mF,dF,                                                          \
0338             c##_##mG,dG,                                                          \
0339             c##_##mH,dH,                                                          \
0340             c##_##mI,dI,                                                          \
0341             c##_##mJ,d)
0342 
0343 #define PUSH_NV_(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,IMPL,...) IMPL
0344 #define PUSH_NV(A...) PUSH_NV_(A, PUSH_NV_10, PUSH_NV_10,       \
0345                   PUSH_NV_9 , PUSH_NV_9,        \
0346                   PUSH_NV_8 , PUSH_NV_8,        \
0347                   PUSH_NV_7 , PUSH_NV_7,        \
0348                   PUSH_NV_6 , PUSH_NV_6,        \
0349                   PUSH_NV_5 , PUSH_NV_5,        \
0350                   PUSH_NV_4 , PUSH_NV_4,        \
0351                   PUSH_NV_3 , PUSH_NV_3,        \
0352                   PUSH_NV_2 , PUSH_NV_2,        \
0353                   PUSH_NV_1 , PUSH_NV_1)(, ##A)
0354 
0355 #define PUSH_IMMD(A...) PUSH_NV(NVIM, ##A)
0356 #define PUSH_MTHD(A...) PUSH_NV(NVSQ, ##A)
0357 #define PUSH_1INC(A...) PUSH_NV(NV1I, ##A)
0358 #define PUSH_NINC(A...) PUSH_NV(NVNI, ##A)
0359 #endif