ctxnv40.h 2.9 KB

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