nouveau_grctx.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #ifndef __NOUVEAU_GRCTX_H__
  2. #define __NOUVEAU_GRCTX_H__
  3. struct nouveau_grctx {
  4. struct drm_device *dev;
  5. enum {
  6. NOUVEAU_GRCTX_PROG,
  7. NOUVEAU_GRCTX_VALS
  8. } mode;
  9. void *data;
  10. uint32_t ctxprog_max;
  11. uint32_t ctxprog_len;
  12. uint32_t ctxprog_reg;
  13. int ctxprog_label[32];
  14. uint32_t ctxvals_pos;
  15. uint32_t ctxvals_base;
  16. };
  17. #ifdef CP_CTX
  18. static inline void
  19. cp_out(struct nouveau_grctx *ctx, uint32_t inst)
  20. {
  21. uint32_t *ctxprog = ctx->data;
  22. if (ctx->mode != NOUVEAU_GRCTX_PROG)
  23. return;
  24. BUG_ON(ctx->ctxprog_len == ctx->ctxprog_max);
  25. ctxprog[ctx->ctxprog_len++] = inst;
  26. }
  27. static inline void
  28. cp_lsr(struct nouveau_grctx *ctx, uint32_t val)
  29. {
  30. cp_out(ctx, CP_LOAD_SR | val);
  31. }
  32. static inline void
  33. cp_ctx(struct nouveau_grctx *ctx, uint32_t reg, uint32_t length)
  34. {
  35. ctx->ctxprog_reg = (reg - 0x00400000) >> 2;
  36. ctx->ctxvals_base = ctx->ctxvals_pos;
  37. ctx->ctxvals_pos = ctx->ctxvals_base + length;
  38. if (length > (CP_CTX_COUNT >> CP_CTX_COUNT_SHIFT)) {
  39. cp_lsr(ctx, length);
  40. length = 0;
  41. }
  42. cp_out(ctx, CP_CTX | (length << CP_CTX_COUNT_SHIFT) | ctx->ctxprog_reg);
  43. }
  44. static inline void
  45. cp_name(struct nouveau_grctx *ctx, int name)
  46. {
  47. uint32_t *ctxprog = ctx->data;
  48. int i;
  49. if (ctx->mode != NOUVEAU_GRCTX_PROG)
  50. return;
  51. ctx->ctxprog_label[name] = ctx->ctxprog_len;
  52. for (i = 0; i < ctx->ctxprog_len; i++) {
  53. if ((ctxprog[i] & 0xfff00000) != 0xff400000)
  54. continue;
  55. if ((ctxprog[i] & CP_BRA_IP) != ((name) << CP_BRA_IP_SHIFT))
  56. continue;
  57. ctxprog[i] = (ctxprog[i] & 0x00ff00ff) |
  58. (ctx->ctxprog_len << CP_BRA_IP_SHIFT);
  59. }
  60. }
  61. static inline void
  62. _cp_bra(struct nouveau_grctx *ctx, u32 mod, int flag, int state, int name)
  63. {
  64. int ip = 0;
  65. if (mod != 2) {
  66. ip = ctx->ctxprog_label[name] << CP_BRA_IP_SHIFT;
  67. if (ip == 0)
  68. ip = 0xff000000 | (name << CP_BRA_IP_SHIFT);
  69. }
  70. cp_out(ctx, CP_BRA | (mod << 18) | ip | flag |
  71. (state ? 0 : CP_BRA_IF_CLEAR));
  72. }
  73. #define cp_bra(c,f,s,n) _cp_bra((c), 0, CP_FLAG_##f, CP_FLAG_##f##_##s, n)
  74. #ifdef CP_BRA_MOD
  75. #define cp_cal(c,f,s,n) _cp_bra((c), 1, CP_FLAG_##f, CP_FLAG_##f##_##s, n)
  76. #define cp_ret(c,f,s) _cp_bra((c), 2, CP_FLAG_##f, CP_FLAG_##f##_##s, 0)
  77. #endif
  78. static inline void
  79. _cp_wait(struct nouveau_grctx *ctx, int flag, int state)
  80. {
  81. cp_out(ctx, CP_WAIT | flag | (state ? CP_WAIT_SET : 0));
  82. }
  83. #define cp_wait(c,f,s) _cp_wait((c), CP_FLAG_##f, CP_FLAG_##f##_##s)
  84. static inline void
  85. _cp_set(struct nouveau_grctx *ctx, int flag, int state)
  86. {
  87. cp_out(ctx, CP_SET | flag | (state ? CP_SET_1 : 0));
  88. }
  89. #define cp_set(c,f,s) _cp_set((c), CP_FLAG_##f, CP_FLAG_##f##_##s)
  90. static inline void
  91. cp_pos(struct nouveau_grctx *ctx, int offset)
  92. {
  93. ctx->ctxvals_pos = offset;
  94. ctx->ctxvals_base = ctx->ctxvals_pos;
  95. cp_lsr(ctx, ctx->ctxvals_pos);
  96. cp_out(ctx, CP_SET_CONTEXT_POINTER);
  97. }
  98. static inline void
  99. gr_def(struct nouveau_grctx *ctx, uint32_t reg, uint32_t val)
  100. {
  101. if (ctx->mode != NOUVEAU_GRCTX_VALS)
  102. return;
  103. reg = (reg - 0x00400000) / 4;
  104. reg = (reg - ctx->ctxprog_reg) + ctx->ctxvals_base;
  105. nv_wo32(ctx->dev, ctx->data, reg, val);
  106. }
  107. #endif
  108. #endif