Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ctx.h
Go to the documentation of this file.
1 #ifndef __NOUVEAU_GRCTX_H__
2 #define __NOUVEAU_GRCTX_H__
3 
4 struct nouveau_grctx {
6 
7  enum {
10  } mode;
11  void *data;
12 
16  int ctxprog_label[32];
19 };
20 
21 static inline void
22 cp_out(struct nouveau_grctx *ctx, u32 inst)
23 {
24  u32 *ctxprog = ctx->data;
25 
26  if (ctx->mode != NOUVEAU_GRCTX_PROG)
27  return;
28 
29  BUG_ON(ctx->ctxprog_len == ctx->ctxprog_max);
30  ctxprog[ctx->ctxprog_len++] = inst;
31 }
32 
33 static inline void
34 cp_lsr(struct nouveau_grctx *ctx, u32 val)
35 {
36  cp_out(ctx, CP_LOAD_SR | val);
37 }
38 
39 static inline void
40 cp_ctx(struct nouveau_grctx *ctx, u32 reg, u32 length)
41 {
42  ctx->ctxprog_reg = (reg - 0x00400000) >> 2;
43 
44  ctx->ctxvals_base = ctx->ctxvals_pos;
45  ctx->ctxvals_pos = ctx->ctxvals_base + length;
46 
47  if (length > (CP_CTX_COUNT >> CP_CTX_COUNT_SHIFT)) {
48  cp_lsr(ctx, length);
49  length = 0;
50  }
51 
52  cp_out(ctx, CP_CTX | (length << CP_CTX_COUNT_SHIFT) | ctx->ctxprog_reg);
53 }
54 
55 static inline void
56 cp_name(struct nouveau_grctx *ctx, int name)
57 {
58  u32 *ctxprog = ctx->data;
59  int i;
60 
61  if (ctx->mode != NOUVEAU_GRCTX_PROG)
62  return;
63 
64  ctx->ctxprog_label[name] = ctx->ctxprog_len;
65  for (i = 0; i < ctx->ctxprog_len; i++) {
66  if ((ctxprog[i] & 0xfff00000) != 0xff400000)
67  continue;
68  if ((ctxprog[i] & CP_BRA_IP) != ((name) << CP_BRA_IP_SHIFT))
69  continue;
70  ctxprog[i] = (ctxprog[i] & 0x00ff00ff) |
71  (ctx->ctxprog_len << CP_BRA_IP_SHIFT);
72  }
73 }
74 
75 static inline void
76 _cp_bra(struct nouveau_grctx *ctx, u32 mod, int flag, int state, int name)
77 {
78  int ip = 0;
79 
80  if (mod != 2) {
81  ip = ctx->ctxprog_label[name] << CP_BRA_IP_SHIFT;
82  if (ip == 0)
83  ip = 0xff000000 | (name << CP_BRA_IP_SHIFT);
84  }
85 
86  cp_out(ctx, CP_BRA | (mod << 18) | ip | flag |
87  (state ? 0 : CP_BRA_IF_CLEAR));
88 }
89 #define cp_bra(c, f, s, n) _cp_bra((c), 0, CP_FLAG_##f, CP_FLAG_##f##_##s, n)
90 #define cp_cal(c, f, s, n) _cp_bra((c), 1, CP_FLAG_##f, CP_FLAG_##f##_##s, n)
91 #define cp_ret(c, f, s) _cp_bra((c), 2, CP_FLAG_##f, CP_FLAG_##f##_##s, 0)
92 
93 static inline void
94 _cp_wait(struct nouveau_grctx *ctx, int flag, int state)
95 {
96  cp_out(ctx, CP_WAIT | flag | (state ? CP_WAIT_SET : 0));
97 }
98 #define cp_wait(c, f, s) _cp_wait((c), CP_FLAG_##f, CP_FLAG_##f##_##s)
99 
100 static inline void
101 _cp_set(struct nouveau_grctx *ctx, int flag, int state)
102 {
103  cp_out(ctx, CP_SET | flag | (state ? CP_SET_1 : 0));
104 }
105 #define cp_set(c, f, s) _cp_set((c), CP_FLAG_##f, CP_FLAG_##f##_##s)
106 
107 static inline void
108 cp_pos(struct nouveau_grctx *ctx, int offset)
109 {
110  ctx->ctxvals_pos = offset;
111  ctx->ctxvals_base = ctx->ctxvals_pos;
112 
113  cp_lsr(ctx, ctx->ctxvals_pos);
114  cp_out(ctx, CP_SET_CONTEXT_POINTER);
115 }
116 
117 static inline void
118 gr_def(struct nouveau_grctx *ctx, u32 reg, u32 val)
119 {
120  if (ctx->mode != NOUVEAU_GRCTX_VALS)
121  return;
122 
123  reg = (reg - 0x00400000) / 4;
124  reg = (reg - ctx->ctxprog_reg) + ctx->ctxvals_base;
125 
126  nv_wo32(ctx->data, reg * 4, val);
127 }
128 
129 #endif