0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
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
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