diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2012-08-13 02:26:07 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2012-10-02 23:13:03 -0400 |
commit | 72a148277701acf56bcec486a1124499600812e1 (patch) | |
tree | b1b53a80b8c4bfd7b7fd731079f35a2d47b51476 | |
parent | 4c2d42225b5024ad88f736608f44b51f702bd4e4 (diff) |
drm/nouveau: restore fifo chid information in engine error messages
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/core/core/engctx.c | 57 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/core/handle.c | 34 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/copy/nva3.c | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/graph/nv20.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/graph/nv40.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/graph/nv50.c | 34 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c | 32 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/graph/nve0.c | 46 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c | 31 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/include/core/engctx.h | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/include/core/handle.h | 5 |
15 files changed, 213 insertions, 132 deletions
diff --git a/drivers/gpu/drm/nouveau/core/core/engctx.c b/drivers/gpu/drm/nouveau/core/core/engctx.c index ad4bbe106b0e..e41b10d5eb59 100644 --- a/drivers/gpu/drm/nouveau/core/core/engctx.c +++ b/drivers/gpu/drm/nouveau/core/core/engctx.c | |||
@@ -59,7 +59,6 @@ nouveau_engctx_create_(struct nouveau_object *parent, | |||
59 | { | 59 | { |
60 | struct nouveau_client *client = nouveau_client(parent); | 60 | struct nouveau_client *client = nouveau_client(parent); |
61 | struct nouveau_engine *engine = nv_engine(engobj); | 61 | struct nouveau_engine *engine = nv_engine(engobj); |
62 | struct nouveau_subdev *subdev = nv_subdev(engine); | ||
63 | struct nouveau_object *engctx; | 62 | struct nouveau_object *engctx; |
64 | unsigned long save; | 63 | unsigned long save; |
65 | int ret; | 64 | int ret; |
@@ -210,58 +209,28 @@ _nouveau_engctx_fini(struct nouveau_object *object, bool suspend) | |||
210 | } | 209 | } |
211 | 210 | ||
212 | struct nouveau_object * | 211 | struct nouveau_object * |
213 | nouveau_engctx_lookup(struct nouveau_engine *engine, u64 addr) | 212 | nouveau_engctx_get(struct nouveau_engine *engine, u64 addr) |
214 | { | 213 | { |
215 | struct nouveau_engctx *engctx; | 214 | struct nouveau_engctx *engctx; |
215 | unsigned long flags; | ||
216 | 216 | ||
217 | spin_lock_irqsave(&engine->lock, flags); | ||
217 | list_for_each_entry(engctx, &engine->contexts, head) { | 218 | list_for_each_entry(engctx, &engine->contexts, head) { |
218 | if (engctx->base.size && | 219 | if (engctx->addr == addr) { |
219 | nv_gpuobj(engctx)->addr == addr) | 220 | engctx->save = flags; |
220 | return nv_object(engctx); | 221 | return nv_object(engctx); |
222 | } | ||
221 | } | 223 | } |
222 | 224 | spin_unlock_irqrestore(&engine->lock, flags); | |
223 | return NULL; | ||
224 | } | ||
225 | |||
226 | struct nouveau_handle * | ||
227 | nouveau_engctx_lookup_class(struct nouveau_engine *engine, u64 addr, u16 oclass) | ||
228 | { | ||
229 | struct nouveau_object *engctx = nouveau_engctx_lookup(engine, addr); | ||
230 | struct nouveau_namedb *namedb; | ||
231 | |||
232 | if (engctx && (namedb = (void *)nv_pclass(engctx, NV_NAMEDB_CLASS))) | ||
233 | return nouveau_namedb_get_class(namedb, oclass); | ||
234 | |||
235 | return NULL; | ||
236 | } | ||
237 | |||
238 | struct nouveau_handle * | ||
239 | nouveau_engctx_lookup_vinst(struct nouveau_engine *engine, u64 addr, u64 vinst) | ||
240 | { | ||
241 | struct nouveau_object *engctx = nouveau_engctx_lookup(engine, addr); | ||
242 | struct nouveau_namedb *namedb; | ||
243 | |||
244 | if (engctx && (namedb = (void *)nv_pclass(engctx, NV_NAMEDB_CLASS))) | ||
245 | return nouveau_namedb_get_vinst(namedb, vinst); | ||
246 | |||
247 | return NULL; | ||
248 | } | ||
249 | |||
250 | struct nouveau_handle * | ||
251 | nouveau_engctx_lookup_cinst(struct nouveau_engine *engine, u64 addr, u32 cinst) | ||
252 | { | ||
253 | struct nouveau_object *engctx = nouveau_engctx_lookup(engine, addr); | ||
254 | struct nouveau_namedb *namedb; | ||
255 | |||
256 | if (engctx && (namedb = (void *)nv_pclass(engctx, NV_NAMEDB_CLASS))) | ||
257 | return nouveau_namedb_get_cinst(namedb, cinst); | ||
258 | |||
259 | return NULL; | 225 | return NULL; |
260 | } | 226 | } |
261 | 227 | ||
262 | void | 228 | void |
263 | nouveau_engctx_handle_put(struct nouveau_handle *handle) | 229 | nouveau_engctx_put(struct nouveau_object *object) |
264 | { | 230 | { |
265 | if (handle) | 231 | if (object) { |
266 | nouveau_namedb_put(handle); | 232 | struct nouveau_engine *engine = nv_engine(object->engine); |
233 | struct nouveau_engctx *engctx = nv_engctx(object); | ||
234 | spin_unlock_irqrestore(&engine->lock, engctx->save); | ||
235 | } | ||
267 | } | 236 | } |
diff --git a/drivers/gpu/drm/nouveau/core/core/handle.c b/drivers/gpu/drm/nouveau/core/core/handle.c index f2ab2e85009c..b8d2cbf8a7a7 100644 --- a/drivers/gpu/drm/nouveau/core/core/handle.c +++ b/drivers/gpu/drm/nouveau/core/core/handle.c | |||
@@ -187,3 +187,37 @@ nouveau_handle_ref(struct nouveau_object *parent, u32 name) | |||
187 | 187 | ||
188 | return object; | 188 | return object; |
189 | } | 189 | } |
190 | |||
191 | struct nouveau_handle * | ||
192 | nouveau_handle_get_class(struct nouveau_object *engctx, u16 oclass) | ||
193 | { | ||
194 | struct nouveau_namedb *namedb; | ||
195 | if (engctx && (namedb = (void *)nv_pclass(engctx, NV_NAMEDB_CLASS))) | ||
196 | return nouveau_namedb_get_class(namedb, oclass); | ||
197 | return NULL; | ||
198 | } | ||
199 | |||
200 | struct nouveau_handle * | ||
201 | nouveau_handle_get_vinst(struct nouveau_object *engctx, u64 vinst) | ||
202 | { | ||
203 | struct nouveau_namedb *namedb; | ||
204 | if (engctx && (namedb = (void *)nv_pclass(engctx, NV_NAMEDB_CLASS))) | ||
205 | return nouveau_namedb_get_vinst(namedb, vinst); | ||
206 | return NULL; | ||
207 | } | ||
208 | |||
209 | struct nouveau_handle * | ||
210 | nouveau_handle_get_cinst(struct nouveau_object *engctx, u32 cinst) | ||
211 | { | ||
212 | struct nouveau_namedb *namedb; | ||
213 | if (engctx && (namedb = (void *)nv_pclass(engctx, NV_NAMEDB_CLASS))) | ||
214 | return nouveau_namedb_get_cinst(namedb, cinst); | ||
215 | return NULL; | ||
216 | } | ||
217 | |||
218 | void | ||
219 | nouveau_handle_put(struct nouveau_handle *handle) | ||
220 | { | ||
221 | if (handle) | ||
222 | nouveau_namedb_put(handle); | ||
223 | } | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c b/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c index debb82830b66..c43c33454a65 100644 --- a/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c +++ b/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <subdev/fb.h> | 30 | #include <subdev/fb.h> |
31 | #include <subdev/vm.h> | 31 | #include <subdev/vm.h> |
32 | 32 | ||
33 | #include <engine/fifo.h> | ||
33 | #include <engine/copy.h> | 34 | #include <engine/copy.h> |
34 | 35 | ||
35 | #include "fuc/nva3.fuc.h" | 36 | #include "fuc/nva3.fuc.h" |
@@ -102,21 +103,28 @@ static struct nouveau_enum nva3_copy_isr_error_name[] = { | |||
102 | static void | 103 | static void |
103 | nva3_copy_intr(struct nouveau_subdev *subdev) | 104 | nva3_copy_intr(struct nouveau_subdev *subdev) |
104 | { | 105 | { |
106 | struct nouveau_fifo *pfifo = nouveau_fifo(subdev); | ||
107 | struct nouveau_engine *engine = nv_engine(subdev); | ||
108 | struct nouveau_object *engctx; | ||
105 | struct nva3_copy_priv *priv = (void *)subdev; | 109 | struct nva3_copy_priv *priv = (void *)subdev; |
106 | u32 dispatch = nv_rd32(priv, 0x10401c); | 110 | u32 dispatch = nv_rd32(priv, 0x10401c); |
107 | u32 stat = nv_rd32(priv, 0x104008) & dispatch & ~(dispatch >> 16); | 111 | u32 stat = nv_rd32(priv, 0x104008) & dispatch & ~(dispatch >> 16); |
108 | u32 inst = nv_rd32(priv, 0x104050) & 0x3fffffff; | 112 | u64 inst = nv_rd32(priv, 0x104050) & 0x3fffffff; |
109 | u32 ssta = nv_rd32(priv, 0x104040) & 0x0000ffff; | 113 | u32 ssta = nv_rd32(priv, 0x104040) & 0x0000ffff; |
110 | u32 addr = nv_rd32(priv, 0x104040) >> 16; | 114 | u32 addr = nv_rd32(priv, 0x104040) >> 16; |
111 | u32 mthd = (addr & 0x07ff) << 2; | 115 | u32 mthd = (addr & 0x07ff) << 2; |
112 | u32 subc = (addr & 0x3800) >> 11; | 116 | u32 subc = (addr & 0x3800) >> 11; |
113 | u32 data = nv_rd32(priv, 0x104044); | 117 | u32 data = nv_rd32(priv, 0x104044); |
118 | int chid; | ||
119 | |||
120 | engctx = nouveau_engctx_get(engine, inst); | ||
121 | chid = pfifo->chid(pfifo, engctx); | ||
114 | 122 | ||
115 | if (stat & 0x00000040) { | 123 | if (stat & 0x00000040) { |
116 | nv_error(priv, "DISPATCH_ERROR ["); | 124 | nv_error(priv, "DISPATCH_ERROR ["); |
117 | nouveau_enum_print(nva3_copy_isr_error_name, ssta); | 125 | nouveau_enum_print(nva3_copy_isr_error_name, ssta); |
118 | printk("] ch 0x%08x subc %d mthd 0x%04x data 0x%08x\n", | 126 | printk("] ch %d [0x%010llx] subc %d mthd 0x%04x data 0x%08x\n", |
119 | inst, subc, mthd, data); | 127 | chid, inst << 12, subc, mthd, data); |
120 | nv_wr32(priv, 0x104004, 0x00000040); | 128 | nv_wr32(priv, 0x104004, 0x00000040); |
121 | stat &= ~0x00000040; | 129 | stat &= ~0x00000040; |
122 | } | 130 | } |
@@ -127,6 +135,7 @@ nva3_copy_intr(struct nouveau_subdev *subdev) | |||
127 | } | 135 | } |
128 | 136 | ||
129 | nv50_fb_trap(nouveau_fb(priv), 1); | 137 | nv50_fb_trap(nouveau_fb(priv), 1); |
138 | nouveau_engctx_put(engctx); | ||
130 | } | 139 | } |
131 | 140 | ||
132 | static int | 141 | static int |
diff --git a/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c index ecc8faac3a2a..0c0ce0fb58da 100644 --- a/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <core/class.h> | 27 | #include <core/class.h> |
28 | #include <core/engctx.h> | 28 | #include <core/engctx.h> |
29 | 29 | ||
30 | #include <engine/fifo.h> | ||
30 | #include <engine/copy.h> | 31 | #include <engine/copy.h> |
31 | 32 | ||
32 | #include "fuc/nvc0.fuc.h" | 33 | #include "fuc/nvc0.fuc.h" |
@@ -113,6 +114,9 @@ static struct nouveau_enum nvc0_copy_isr_error_name[] = { | |||
113 | static void | 114 | static void |
114 | nvc0_copy_intr(struct nouveau_subdev *subdev) | 115 | nvc0_copy_intr(struct nouveau_subdev *subdev) |
115 | { | 116 | { |
117 | struct nouveau_fifo *pfifo = nouveau_fifo(subdev); | ||
118 | struct nouveau_engine *engine = nv_engine(subdev); | ||
119 | struct nouveau_object *engctx; | ||
116 | int idx = nv_engidx(nv_object(subdev)) - NVDEV_ENGINE_COPY0; | 120 | int idx = nv_engidx(nv_object(subdev)) - NVDEV_ENGINE_COPY0; |
117 | struct nvc0_copy_priv *priv = (void *)subdev; | 121 | struct nvc0_copy_priv *priv = (void *)subdev; |
118 | u32 disp = nv_rd32(priv, 0x10401c + (idx * 0x1000)); | 122 | u32 disp = nv_rd32(priv, 0x10401c + (idx * 0x1000)); |
@@ -124,12 +128,16 @@ nvc0_copy_intr(struct nouveau_subdev *subdev) | |||
124 | u32 mthd = (addr & 0x07ff) << 2; | 128 | u32 mthd = (addr & 0x07ff) << 2; |
125 | u32 subc = (addr & 0x3800) >> 11; | 129 | u32 subc = (addr & 0x3800) >> 11; |
126 | u32 data = nv_rd32(priv, 0x104044 + (idx * 0x1000)); | 130 | u32 data = nv_rd32(priv, 0x104044 + (idx * 0x1000)); |
131 | int chid; | ||
132 | |||
133 | engctx = nouveau_engctx_get(engine, inst); | ||
134 | chid = pfifo->chid(pfifo, engctx); | ||
127 | 135 | ||
128 | if (stat & 0x00000040) { | 136 | if (stat & 0x00000040) { |
129 | nv_error(priv, "DISPATCH_ERROR ["); | 137 | nv_error(priv, "DISPATCH_ERROR ["); |
130 | nouveau_enum_print(nvc0_copy_isr_error_name, ssta); | 138 | nouveau_enum_print(nvc0_copy_isr_error_name, ssta); |
131 | printk("] ch 0x%010llx subc %d mthd 0x%04x data 0x%08x\n", | 139 | printk("] ch %d [0x%010llx] subc %d mthd 0x%04x data 0x%08x\n", |
132 | (u64)inst << 12, subc, mthd, data); | 140 | chid, (u64)inst << 12, subc, mthd, data); |
133 | nv_wr32(priv, 0x104004 + (idx * 0x1000), 0x00000040); | 141 | nv_wr32(priv, 0x104004 + (idx * 0x1000), 0x00000040); |
134 | stat &= ~0x00000040; | 142 | stat &= ~0x00000040; |
135 | } | 143 | } |
@@ -138,6 +146,8 @@ nvc0_copy_intr(struct nouveau_subdev *subdev) | |||
138 | nv_error(priv, "unhandled intr 0x%08x\n", stat); | 146 | nv_error(priv, "unhandled intr 0x%08x\n", stat); |
139 | nv_wr32(priv, 0x104004 + (idx * 0x1000), stat); | 147 | nv_wr32(priv, 0x104004 + (idx * 0x1000), stat); |
140 | } | 148 | } |
149 | |||
150 | nouveau_engctx_put(engctx); | ||
141 | } | 151 | } |
142 | 152 | ||
143 | static int | 153 | static int |
diff --git a/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c b/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c index a0e5e39638bc..198989b21c28 100644 --- a/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c +++ b/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | #include <subdev/fb.h> | 31 | #include <subdev/fb.h> |
32 | 32 | ||
33 | #include <engine/fifo.h> | ||
33 | #include <engine/crypt.h> | 34 | #include <engine/crypt.h> |
34 | 35 | ||
35 | struct nv84_crypt_priv { | 36 | struct nv84_crypt_priv { |
@@ -133,23 +134,31 @@ static struct nouveau_bitfield nv84_crypt_intr_mask[] = { | |||
133 | static void | 134 | static void |
134 | nv84_crypt_intr(struct nouveau_subdev *subdev) | 135 | nv84_crypt_intr(struct nouveau_subdev *subdev) |
135 | { | 136 | { |
137 | struct nouveau_fifo *pfifo = nouveau_fifo(subdev); | ||
138 | struct nouveau_engine *engine = nv_engine(subdev); | ||
139 | struct nouveau_object *engctx; | ||
136 | struct nv84_crypt_priv *priv = (void *)subdev; | 140 | struct nv84_crypt_priv *priv = (void *)subdev; |
137 | u32 stat = nv_rd32(priv, 0x102130); | 141 | u32 stat = nv_rd32(priv, 0x102130); |
138 | u32 mthd = nv_rd32(priv, 0x102190); | 142 | u32 mthd = nv_rd32(priv, 0x102190); |
139 | u32 data = nv_rd32(priv, 0x102194); | 143 | u32 data = nv_rd32(priv, 0x102194); |
140 | u32 inst = nv_rd32(priv, 0x102188) & 0x7fffffff; | 144 | u32 inst = nv_rd32(priv, 0x102188) & 0x7fffffff; |
145 | int chid; | ||
146 | |||
147 | engctx = nouveau_engctx_get(engine, inst); | ||
148 | chid = pfifo->chid(pfifo, engctx); | ||
141 | 149 | ||
142 | if (stat) { | 150 | if (stat) { |
143 | nv_error(priv, ""); | 151 | nv_error(priv, ""); |
144 | nouveau_bitfield_print(nv84_crypt_intr_mask, stat); | 152 | nouveau_bitfield_print(nv84_crypt_intr_mask, stat); |
145 | printk(" ch 0x%010llx mthd 0x%04x data 0x%08x\n", | 153 | printk(" ch %d [0x%010llx] mthd 0x%04x data 0x%08x\n", |
146 | (u64)inst << 12, mthd, data); | 154 | chid, (u64)inst << 12, mthd, data); |
147 | } | 155 | } |
148 | 156 | ||
149 | nv_wr32(priv, 0x102130, stat); | 157 | nv_wr32(priv, 0x102130, stat); |
150 | nv_wr32(priv, 0x10200c, 0x10); | 158 | nv_wr32(priv, 0x10200c, 0x10); |
151 | 159 | ||
152 | nv50_fb_trap(nouveau_fb(priv), 1); | 160 | nv50_fb_trap(nouveau_fb(priv), 1); |
161 | nouveau_engctx_put(engctx); | ||
153 | } | 162 | } |
154 | 163 | ||
155 | static int | 164 | static int |
diff --git a/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c b/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c index 559a1b1d7082..835b8eb22596 100644 --- a/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c +++ b/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <subdev/timer.h> | 30 | #include <subdev/timer.h> |
31 | #include <subdev/fb.h> | 31 | #include <subdev/fb.h> |
32 | 32 | ||
33 | #include <engine/fifo.h> | ||
33 | #include <engine/crypt.h> | 34 | #include <engine/crypt.h> |
34 | 35 | ||
35 | #include "fuc/nv98.fuc.h" | 36 | #include "fuc/nv98.fuc.h" |
@@ -102,6 +103,9 @@ static struct nouveau_enum nv98_crypt_isr_error_name[] = { | |||
102 | static void | 103 | static void |
103 | nv98_crypt_intr(struct nouveau_subdev *subdev) | 104 | nv98_crypt_intr(struct nouveau_subdev *subdev) |
104 | { | 105 | { |
106 | struct nouveau_fifo *pfifo = nouveau_fifo(subdev); | ||
107 | struct nouveau_engine *engine = nv_engine(subdev); | ||
108 | struct nouveau_object *engctx; | ||
105 | struct nv98_crypt_priv *priv = (void *)subdev; | 109 | struct nv98_crypt_priv *priv = (void *)subdev; |
106 | u32 disp = nv_rd32(priv, 0x08701c); | 110 | u32 disp = nv_rd32(priv, 0x08701c); |
107 | u32 stat = nv_rd32(priv, 0x087008) & disp & ~(disp >> 16); | 111 | u32 stat = nv_rd32(priv, 0x087008) & disp & ~(disp >> 16); |
@@ -111,12 +115,16 @@ nv98_crypt_intr(struct nouveau_subdev *subdev) | |||
111 | u32 mthd = (addr & 0x07ff) << 2; | 115 | u32 mthd = (addr & 0x07ff) << 2; |
112 | u32 subc = (addr & 0x3800) >> 11; | 116 | u32 subc = (addr & 0x3800) >> 11; |
113 | u32 data = nv_rd32(priv, 0x087044); | 117 | u32 data = nv_rd32(priv, 0x087044); |
118 | int chid; | ||
119 | |||
120 | engctx = nouveau_engctx_get(engine, inst); | ||
121 | chid = pfifo->chid(pfifo, engctx); | ||
114 | 122 | ||
115 | if (stat & 0x00000040) { | 123 | if (stat & 0x00000040) { |
116 | nv_error(priv, "DISPATCH_ERROR ["); | 124 | nv_error(priv, "DISPATCH_ERROR ["); |
117 | nouveau_enum_print(nv98_crypt_isr_error_name, ssta); | 125 | nouveau_enum_print(nv98_crypt_isr_error_name, ssta); |
118 | printk("] ch 0x%08x subc %d mthd 0x%04x data 0x%08x\n", | 126 | printk("] ch %d [0x%010llx] subc %d mthd 0x%04x data 0x%08x\n", |
119 | inst, subc, mthd, data); | 127 | chid, (u64)inst << 12, subc, mthd, data); |
120 | nv_wr32(priv, 0x087004, 0x00000040); | 128 | nv_wr32(priv, 0x087004, 0x00000040); |
121 | stat &= ~0x00000040; | 129 | stat &= ~0x00000040; |
122 | } | 130 | } |
@@ -127,6 +135,7 @@ nv98_crypt_intr(struct nouveau_subdev *subdev) | |||
127 | } | 135 | } |
128 | 136 | ||
129 | nv50_fb_trap(nouveau_fb(priv), 1); | 137 | nv50_fb_trap(nouveau_fb(priv), 1); |
138 | nouveau_engctx_put(engctx); | ||
130 | } | 139 | } |
131 | 140 | ||
132 | static int | 141 | static int |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c index 61faef976aee..8f3f619c4a78 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c | |||
@@ -195,9 +195,10 @@ nv20_graph_tile_prog(struct nouveau_engine *engine, int i) | |||
195 | void | 195 | void |
196 | nv20_graph_intr(struct nouveau_subdev *subdev) | 196 | nv20_graph_intr(struct nouveau_subdev *subdev) |
197 | { | 197 | { |
198 | struct nv20_graph_priv *priv = (void *)subdev; | ||
199 | struct nouveau_engine *engine = nv_engine(subdev); | 198 | struct nouveau_engine *engine = nv_engine(subdev); |
200 | struct nouveau_handle *handle = NULL; | 199 | struct nouveau_object *engctx; |
200 | struct nouveau_handle *handle; | ||
201 | struct nv20_graph_priv *priv = (void *)subdev; | ||
201 | u32 stat = nv_rd32(priv, NV03_PGRAPH_INTR); | 202 | u32 stat = nv_rd32(priv, NV03_PGRAPH_INTR); |
202 | u32 nsource = nv_rd32(priv, NV03_PGRAPH_NSOURCE); | 203 | u32 nsource = nv_rd32(priv, NV03_PGRAPH_NSOURCE); |
203 | u32 nstatus = nv_rd32(priv, NV03_PGRAPH_NSTATUS); | 204 | u32 nstatus = nv_rd32(priv, NV03_PGRAPH_NSTATUS); |
@@ -207,15 +208,15 @@ nv20_graph_intr(struct nouveau_subdev *subdev) | |||
207 | u32 mthd = (addr & 0x00001ffc); | 208 | u32 mthd = (addr & 0x00001ffc); |
208 | u32 data = nv_rd32(priv, NV04_PGRAPH_TRAPPED_DATA); | 209 | u32 data = nv_rd32(priv, NV04_PGRAPH_TRAPPED_DATA); |
209 | u32 class = nv_rd32(priv, 0x400160 + subc * 4) & 0xfff; | 210 | u32 class = nv_rd32(priv, 0x400160 + subc * 4) & 0xfff; |
210 | u32 inst = nv_ro32(priv->ctxtab, (chid * 4)) << 4; | ||
211 | u32 show = stat; | 211 | u32 show = stat; |
212 | 212 | ||
213 | engctx = nouveau_engctx_get(engine, chid); | ||
213 | if (stat & NV_PGRAPH_INTR_ERROR) { | 214 | if (stat & NV_PGRAPH_INTR_ERROR) { |
214 | if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { | 215 | if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { |
215 | handle = nouveau_engctx_lookup_class(engine, inst, class); | 216 | handle = nouveau_handle_get_class(engctx, class); |
216 | if (handle && !nv_call(handle->object, mthd, data)) | 217 | if (handle && !nv_call(handle->object, mthd, data)) |
217 | show &= ~NV_PGRAPH_INTR_ERROR; | 218 | show &= ~NV_PGRAPH_INTR_ERROR; |
218 | nouveau_engctx_handle_put(handle); | 219 | nouveau_handle_put(handle); |
219 | } | 220 | } |
220 | } | 221 | } |
221 | 222 | ||
@@ -233,6 +234,8 @@ nv20_graph_intr(struct nouveau_subdev *subdev) | |||
233 | nv_info(priv, "ch %d/%d class 0x%04x mthd 0x%04x data 0x%08x\n", | 234 | nv_info(priv, "ch %d/%d class 0x%04x mthd 0x%04x data 0x%08x\n", |
234 | chid, subc, class, mthd, data); | 235 | chid, subc, class, mthd, data); |
235 | } | 236 | } |
237 | |||
238 | nouveau_engctx_put(engctx); | ||
236 | } | 239 | } |
237 | 240 | ||
238 | static int | 241 | static int |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c index 2f9f2c69d1e3..5690fe37d660 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c | |||
@@ -256,26 +256,32 @@ nv40_graph_tile_prog(struct nouveau_engine *engine, int i) | |||
256 | static void | 256 | static void |
257 | nv40_graph_intr(struct nouveau_subdev *subdev) | 257 | nv40_graph_intr(struct nouveau_subdev *subdev) |
258 | { | 258 | { |
259 | struct nv40_graph_priv *priv = (void *)subdev; | 259 | struct nouveau_fifo *pfifo = nouveau_fifo(subdev); |
260 | struct nouveau_engine *engine = nv_engine(subdev); | 260 | struct nouveau_engine *engine = nv_engine(subdev); |
261 | struct nouveau_object *engctx; | ||
261 | struct nouveau_handle *handle = NULL; | 262 | struct nouveau_handle *handle = NULL; |
263 | struct nv40_graph_priv *priv = (void *)subdev; | ||
262 | u32 stat = nv_rd32(priv, NV03_PGRAPH_INTR); | 264 | u32 stat = nv_rd32(priv, NV03_PGRAPH_INTR); |
263 | u32 nsource = nv_rd32(priv, NV03_PGRAPH_NSOURCE); | 265 | u32 nsource = nv_rd32(priv, NV03_PGRAPH_NSOURCE); |
264 | u32 nstatus = nv_rd32(priv, NV03_PGRAPH_NSTATUS); | 266 | u32 nstatus = nv_rd32(priv, NV03_PGRAPH_NSTATUS); |
265 | u32 inst = (nv_rd32(priv, 0x40032c) & 0x000fffff) << 4; | 267 | u32 inst = nv_rd32(priv, 0x40032c) & 0x000fffff; |
266 | u32 addr = nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR); | 268 | u32 addr = nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR); |
267 | u32 subc = (addr & 0x00070000) >> 16; | 269 | u32 subc = (addr & 0x00070000) >> 16; |
268 | u32 mthd = (addr & 0x00001ffc); | 270 | u32 mthd = (addr & 0x00001ffc); |
269 | u32 data = nv_rd32(priv, NV04_PGRAPH_TRAPPED_DATA); | 271 | u32 data = nv_rd32(priv, NV04_PGRAPH_TRAPPED_DATA); |
270 | u32 class = nv_rd32(priv, 0x400160 + subc * 4) & 0xffff; | 272 | u32 class = nv_rd32(priv, 0x400160 + subc * 4) & 0xffff; |
271 | u32 show = stat; | 273 | u32 show = stat; |
274 | int chid; | ||
275 | |||
276 | engctx = nouveau_engctx_get(engine, inst); | ||
277 | chid = pfifo->chid(pfifo, engctx); | ||
272 | 278 | ||
273 | if (stat & NV_PGRAPH_INTR_ERROR) { | 279 | if (stat & NV_PGRAPH_INTR_ERROR) { |
274 | if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { | 280 | if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { |
275 | handle = nouveau_engctx_lookup_class(engine, inst, class); | 281 | handle = nouveau_handle_get_class(engctx, class); |
276 | if (handle && !nv_call(handle->object, mthd, data)) | 282 | if (handle && !nv_call(handle->object, mthd, data)) |
277 | show &= ~NV_PGRAPH_INTR_ERROR; | 283 | show &= ~NV_PGRAPH_INTR_ERROR; |
278 | nouveau_engctx_handle_put(handle); | 284 | nouveau_handle_put(handle); |
279 | } | 285 | } |
280 | 286 | ||
281 | if (nsource & NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION) { | 287 | if (nsource & NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION) { |
@@ -294,10 +300,12 @@ nv40_graph_intr(struct nouveau_subdev *subdev) | |||
294 | printk(" nstatus:"); | 300 | printk(" nstatus:"); |
295 | nouveau_bitfield_print(nv10_graph_nstatus, nstatus); | 301 | nouveau_bitfield_print(nv10_graph_nstatus, nstatus); |
296 | printk("\n"); | 302 | printk("\n"); |
297 | nv_error(priv, "ch 0x%08x subc %d class 0x%04x " | 303 | nv_error(priv, "ch %d [0x%08x] subc %d class 0x%04x " |
298 | "mthd 0x%04x data 0x%08x\n", | 304 | "mthd 0x%04x data 0x%08x\n", |
299 | inst, subc, class, mthd, data); | 305 | chid, inst << 4, subc, class, mthd, data); |
300 | } | 306 | } |
307 | |||
308 | nouveau_engctx_put(engctx); | ||
301 | } | 309 | } |
302 | 310 | ||
303 | static int | 311 | static int |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c index 8955bdd3551c..c93b5258eaec 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <subdev/vm.h> | 32 | #include <subdev/vm.h> |
33 | #include <subdev/timer.h> | 33 | #include <subdev/timer.h> |
34 | 34 | ||
35 | #include <engine/fifo.h> | ||
35 | #include <engine/graph.h> | 36 | #include <engine/graph.h> |
36 | 37 | ||
37 | #include "nv50.h" | 38 | #include "nv50.h" |
@@ -462,7 +463,8 @@ nv50_priv_tp_trap(struct nv50_graph_priv *priv, int type, u32 ustatus_old, | |||
462 | } | 463 | } |
463 | 464 | ||
464 | static int | 465 | static int |
465 | nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display, u64 inst) | 466 | nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display, |
467 | int chid, u64 inst) | ||
466 | { | 468 | { |
467 | u32 status = nv_rd32(priv, 0x400108); | 469 | u32 status = nv_rd32(priv, 0x400108); |
468 | u32 ustatus; | 470 | u32 ustatus; |
@@ -495,11 +497,11 @@ nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display, u64 inst) | |||
495 | 497 | ||
496 | nv_error(priv, "TRAP DISPATCH_FAULT\n"); | 498 | nv_error(priv, "TRAP DISPATCH_FAULT\n"); |
497 | if (display && (addr & 0x80000000)) { | 499 | if (display && (addr & 0x80000000)) { |
498 | nv_error(priv, "ch 0x%010llx " | 500 | nv_error(priv, "ch %d [0x%010llx] " |
499 | "subc %d class 0x%04x mthd 0x%04x " | 501 | "subc %d class 0x%04x mthd 0x%04x " |
500 | "data 0x%08x%08x " | 502 | "data 0x%08x%08x " |
501 | "400808 0x%08x 400848 0x%08x\n", | 503 | "400808 0x%08x 400848 0x%08x\n", |
502 | inst, subc, class, mthd, datah, | 504 | chid, inst, subc, class, mthd, datah, |
503 | datal, addr, r848); | 505 | datal, addr, r848); |
504 | } else | 506 | } else |
505 | if (display) { | 507 | if (display) { |
@@ -521,10 +523,10 @@ nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display, u64 inst) | |||
521 | 523 | ||
522 | nv_error(priv, "TRAP DISPATCH_QUERY\n"); | 524 | nv_error(priv, "TRAP DISPATCH_QUERY\n"); |
523 | if (display && (addr & 0x80000000)) { | 525 | if (display && (addr & 0x80000000)) { |
524 | nv_error(priv, "ch 0x%010llx " | 526 | nv_error(priv, "ch %d [0x%010llx] " |
525 | "subc %d class 0x%04x mthd 0x%04x " | 527 | "subc %d class 0x%04x mthd 0x%04x " |
526 | "data 0x%08x 40084c 0x%08x\n", | 528 | "data 0x%08x 40084c 0x%08x\n", |
527 | inst, subc, class, mthd, | 529 | chid, inst, subc, class, mthd, |
528 | data, addr); | 530 | data, addr); |
529 | } else | 531 | } else |
530 | if (display) { | 532 | if (display) { |
@@ -675,23 +677,29 @@ nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display, u64 inst) | |||
675 | static void | 677 | static void |
676 | nv50_graph_intr(struct nouveau_subdev *subdev) | 678 | nv50_graph_intr(struct nouveau_subdev *subdev) |
677 | { | 679 | { |
678 | struct nv50_graph_priv *priv = (void *)subdev; | 680 | struct nouveau_fifo *pfifo = nouveau_fifo(subdev); |
679 | struct nouveau_engine *engine = nv_engine(subdev); | 681 | struct nouveau_engine *engine = nv_engine(subdev); |
682 | struct nouveau_object *engctx; | ||
680 | struct nouveau_handle *handle = NULL; | 683 | struct nouveau_handle *handle = NULL; |
684 | struct nv50_graph_priv *priv = (void *)subdev; | ||
681 | u32 stat = nv_rd32(priv, 0x400100); | 685 | u32 stat = nv_rd32(priv, 0x400100); |
682 | u64 inst = (u64)(nv_rd32(priv, 0x40032c) & 0x0fffffff) << 12; | 686 | u32 inst = nv_rd32(priv, 0x40032c) & 0x0fffffff; |
683 | u32 addr = nv_rd32(priv, 0x400704); | 687 | u32 addr = nv_rd32(priv, 0x400704); |
684 | u32 subc = (addr & 0x00070000) >> 16; | 688 | u32 subc = (addr & 0x00070000) >> 16; |
685 | u32 mthd = (addr & 0x00001ffc); | 689 | u32 mthd = (addr & 0x00001ffc); |
686 | u32 data = nv_rd32(priv, 0x400708); | 690 | u32 data = nv_rd32(priv, 0x400708); |
687 | u32 class = nv_rd32(priv, 0x400814); | 691 | u32 class = nv_rd32(priv, 0x400814); |
688 | u32 show = stat; | 692 | u32 show = stat; |
693 | int chid; | ||
694 | |||
695 | engctx = nouveau_engctx_get(engine, inst); | ||
696 | chid = pfifo->chid(pfifo, engctx); | ||
689 | 697 | ||
690 | if (stat & 0x00000010) { | 698 | if (stat & 0x00000010) { |
691 | handle = nouveau_engctx_lookup_class(engine, inst, class); | 699 | handle = nouveau_handle_get_class(engctx, class); |
692 | if (handle && !nv_call(handle->object, mthd, data)) | 700 | if (handle && !nv_call(handle->object, mthd, data)) |
693 | show &= ~0x00000010; | 701 | show &= ~0x00000010; |
694 | nouveau_engctx_handle_put(handle); | 702 | nouveau_handle_put(handle); |
695 | } | 703 | } |
696 | 704 | ||
697 | if (show & 0x00100000) { | 705 | if (show & 0x00100000) { |
@@ -702,7 +710,7 @@ nv50_graph_intr(struct nouveau_subdev *subdev) | |||
702 | } | 710 | } |
703 | 711 | ||
704 | if (stat & 0x00200000) { | 712 | if (stat & 0x00200000) { |
705 | if (!nv50_graph_trap_handler(priv, show, inst)) | 713 | if (!nv50_graph_trap_handler(priv, show, chid, (u64)inst << 12)) |
706 | show &= ~0x00200000; | 714 | show &= ~0x00200000; |
707 | } | 715 | } |
708 | 716 | ||
@@ -713,14 +721,16 @@ nv50_graph_intr(struct nouveau_subdev *subdev) | |||
713 | nv_info(priv, ""); | 721 | nv_info(priv, ""); |
714 | nouveau_bitfield_print(nv50_graph_intr_name, show); | 722 | nouveau_bitfield_print(nv50_graph_intr_name, show); |
715 | printk("\n"); | 723 | printk("\n"); |
716 | nv_error(priv, "ch 0x%010llx subc %d class 0x%04x " | 724 | nv_error(priv, "ch %d [0x%010llx] subc %d class 0x%04x " |
717 | "mthd 0x%04x data 0x%08x\n", | 725 | "mthd 0x%04x data 0x%08x\n", |
718 | inst, subc, class, mthd, data); | 726 | chid, (u64)inst << 12, subc, class, mthd, data); |
719 | nv50_fb_trap(nouveau_fb(priv), 1); | 727 | nv50_fb_trap(nouveau_fb(priv), 1); |
720 | } | 728 | } |
721 | 729 | ||
722 | if (nv_rd32(priv, 0x400824) & (1 << 31)) | 730 | if (nv_rd32(priv, 0x400824) & (1 << 31)) |
723 | nv_wr32(priv, 0x400824, nv_rd32(priv, 0x400824) & ~(1 << 31)); | 731 | nv_wr32(priv, 0x400824, nv_rd32(priv, 0x400824) & ~(1 << 31)); |
732 | |||
733 | nouveau_engctx_put(engctx); | ||
724 | } | 734 | } |
725 | 735 | ||
726 | static int | 736 | static int |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c index e2f1bea53540..f002e7e91318 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c | |||
@@ -226,10 +226,12 @@ nvc0_graph_ctxctl_isr(struct nvc0_graph_priv *priv) | |||
226 | static void | 226 | static void |
227 | nvc0_graph_intr(struct nouveau_subdev *subdev) | 227 | nvc0_graph_intr(struct nouveau_subdev *subdev) |
228 | { | 228 | { |
229 | struct nvc0_graph_priv *priv = (void *)subdev; | 229 | struct nouveau_fifo *pfifo = nouveau_fifo(subdev); |
230 | struct nouveau_engine *engine = nv_engine(subdev); | 230 | struct nouveau_engine *engine = nv_engine(subdev); |
231 | struct nouveau_handle *handle = NULL; | 231 | struct nouveau_object *engctx; |
232 | u64 inst = (u64)(nv_rd32(priv, 0x409b00) & 0x0fffffff) << 12; | 232 | struct nouveau_handle *handle; |
233 | struct nvc0_graph_priv *priv = (void *)subdev; | ||
234 | u64 inst = nv_rd32(priv, 0x409b00) & 0x0fffffff; | ||
233 | u32 stat = nv_rd32(priv, 0x400100); | 235 | u32 stat = nv_rd32(priv, 0x400100); |
234 | u32 addr = nv_rd32(priv, 0x400704); | 236 | u32 addr = nv_rd32(priv, 0x400704); |
235 | u32 mthd = (addr & 0x00003ffc); | 237 | u32 mthd = (addr & 0x00003ffc); |
@@ -237,24 +239,28 @@ nvc0_graph_intr(struct nouveau_subdev *subdev) | |||
237 | u32 data = nv_rd32(priv, 0x400708); | 239 | u32 data = nv_rd32(priv, 0x400708); |
238 | u32 code = nv_rd32(priv, 0x400110); | 240 | u32 code = nv_rd32(priv, 0x400110); |
239 | u32 class = nv_rd32(priv, 0x404200 + (subc * 4)); | 241 | u32 class = nv_rd32(priv, 0x404200 + (subc * 4)); |
242 | int chid; | ||
243 | |||
244 | engctx = nouveau_engctx_get(engine, inst); | ||
245 | chid = pfifo->chid(pfifo, engctx); | ||
240 | 246 | ||
241 | if (stat & 0x00000010) { | 247 | if (stat & 0x00000010) { |
242 | handle = nouveau_engctx_lookup_class(engine, inst, class); | 248 | handle = nouveau_handle_get_class(engctx, class); |
243 | if (!handle || nv_call(handle->object, mthd, data)) { | 249 | if (!handle || nv_call(handle->object, mthd, data)) { |
244 | nv_error(priv, "ILLEGAL_MTHD ch 0x%010llx " | 250 | nv_error(priv, "ILLEGAL_MTHD ch %d [0x%010llx] " |
245 | "subc %d class 0x%04x mthd 0x%04x " | 251 | "subc %d class 0x%04x mthd 0x%04x " |
246 | "data 0x%08x\n", | 252 | "data 0x%08x\n", |
247 | inst, subc, class, mthd, data); | 253 | chid, inst << 12, subc, class, mthd, data); |
248 | } | 254 | } |
249 | nouveau_engctx_handle_put(handle); | 255 | nouveau_handle_put(handle); |
250 | nv_wr32(priv, 0x400100, 0x00000010); | 256 | nv_wr32(priv, 0x400100, 0x00000010); |
251 | stat &= ~0x00000010; | 257 | stat &= ~0x00000010; |
252 | } | 258 | } |
253 | 259 | ||
254 | if (stat & 0x00000020) { | 260 | if (stat & 0x00000020) { |
255 | nv_error(priv, "ILLEGAL_CLASS ch 0x%010llx subc %d " | 261 | nv_error(priv, "ILLEGAL_CLASS ch %d [0x%010llx] subc %d " |
256 | "class 0x%04x mthd 0x%04x data 0x%08x\n", | 262 | "class 0x%04x mthd 0x%04x data 0x%08x\n", |
257 | inst, subc, class, mthd, data); | 263 | chid, inst << 12, subc, class, mthd, data); |
258 | nv_wr32(priv, 0x400100, 0x00000020); | 264 | nv_wr32(priv, 0x400100, 0x00000020); |
259 | stat &= ~0x00000020; | 265 | stat &= ~0x00000020; |
260 | } | 266 | } |
@@ -262,16 +268,17 @@ nvc0_graph_intr(struct nouveau_subdev *subdev) | |||
262 | if (stat & 0x00100000) { | 268 | if (stat & 0x00100000) { |
263 | nv_error(priv, "DATA_ERROR ["); | 269 | nv_error(priv, "DATA_ERROR ["); |
264 | nouveau_enum_print(nv50_data_error_names, code); | 270 | nouveau_enum_print(nv50_data_error_names, code); |
265 | printk("] ch 0x%010llx subc %d class 0x%04x " | 271 | printk("] ch %d [0x%010llx] subc %d class 0x%04x " |
266 | "mthd 0x%04x data 0x%08x\n", | 272 | "mthd 0x%04x data 0x%08x\n", |
267 | inst, subc, class, mthd, data); | 273 | chid, inst << 12, subc, class, mthd, data); |
268 | nv_wr32(priv, 0x400100, 0x00100000); | 274 | nv_wr32(priv, 0x400100, 0x00100000); |
269 | stat &= ~0x00100000; | 275 | stat &= ~0x00100000; |
270 | } | 276 | } |
271 | 277 | ||
272 | if (stat & 0x00200000) { | 278 | if (stat & 0x00200000) { |
273 | u32 trap = nv_rd32(priv, 0x400108); | 279 | u32 trap = nv_rd32(priv, 0x400108); |
274 | nv_error(priv, "TRAP ch 0x%010llx status 0x%08x\n", inst, trap); | 280 | nv_error(priv, "TRAP ch %d [0x%010llx] status 0x%08x\n", |
281 | chid, inst << 12, trap); | ||
275 | nv_wr32(priv, 0x400108, trap); | 282 | nv_wr32(priv, 0x400108, trap); |
276 | nv_wr32(priv, 0x400100, 0x00200000); | 283 | nv_wr32(priv, 0x400100, 0x00200000); |
277 | stat &= ~0x00200000; | 284 | stat &= ~0x00200000; |
@@ -289,6 +296,7 @@ nvc0_graph_intr(struct nouveau_subdev *subdev) | |||
289 | } | 296 | } |
290 | 297 | ||
291 | nv_wr32(priv, 0x400500, 0x00010001); | 298 | nv_wr32(priv, 0x400500, 0x00010001); |
299 | nouveau_engctx_put(engctx); | ||
292 | } | 300 | } |
293 | 301 | ||
294 | int | 302 | int |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h index 26f8268cc8c2..18d2210e12eb 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <subdev/bar.h> | 35 | #include <subdev/bar.h> |
36 | #include <subdev/timer.h> | 36 | #include <subdev/timer.h> |
37 | 37 | ||
38 | #include <engine/fifo.h> | ||
38 | #include <engine/graph.h> | 39 | #include <engine/graph.h> |
39 | 40 | ||
40 | #define GPC_MAX 4 | 41 | #define GPC_MAX 4 |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c index 7ef692b92e83..2ba125bb5f37 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c | |||
@@ -76,14 +76,15 @@ nve0_graph_ctxctl_isr(struct nvc0_graph_priv *priv) | |||
76 | } | 76 | } |
77 | 77 | ||
78 | static void | 78 | static void |
79 | nve0_graph_trap_isr(struct nvc0_graph_priv *priv, u64 inst) | 79 | nve0_graph_trap_isr(struct nvc0_graph_priv *priv, int chid, u64 inst) |
80 | { | 80 | { |
81 | u32 trap = nv_rd32(priv, 0x400108); | 81 | u32 trap = nv_rd32(priv, 0x400108); |
82 | int rop; | 82 | int rop; |
83 | 83 | ||
84 | if (trap & 0x00000001) { | 84 | if (trap & 0x00000001) { |
85 | u32 stat = nv_rd32(priv, 0x404000); | 85 | u32 stat = nv_rd32(priv, 0x404000); |
86 | nv_error(priv, "DISPATCH ch 0x%010llx 0x%08x\n", inst, stat); | 86 | nv_error(priv, "DISPATCH ch %d [0x%010llx] 0x%08x\n", |
87 | chid, inst, stat); | ||
87 | nv_wr32(priv, 0x404000, 0xc0000000); | 88 | nv_wr32(priv, 0x404000, 0xc0000000); |
88 | nv_wr32(priv, 0x400108, 0x00000001); | 89 | nv_wr32(priv, 0x400108, 0x00000001); |
89 | trap &= ~0x00000001; | 90 | trap &= ~0x00000001; |
@@ -91,7 +92,8 @@ nve0_graph_trap_isr(struct nvc0_graph_priv *priv, u64 inst) | |||
91 | 92 | ||
92 | if (trap & 0x00000010) { | 93 | if (trap & 0x00000010) { |
93 | u32 stat = nv_rd32(priv, 0x405840); | 94 | u32 stat = nv_rd32(priv, 0x405840); |
94 | nv_error(priv, "SHADER ch 0x%010llx 0x%08x\n", inst, stat); | 95 | nv_error(priv, "SHADER ch %d [0x%010llx] 0x%08x\n", |
96 | chid, inst, stat); | ||
95 | nv_wr32(priv, 0x405840, 0xc0000000); | 97 | nv_wr32(priv, 0x405840, 0xc0000000); |
96 | nv_wr32(priv, 0x400108, 0x00000010); | 98 | nv_wr32(priv, 0x400108, 0x00000010); |
97 | trap &= ~0x00000010; | 99 | trap &= ~0x00000010; |
@@ -101,8 +103,8 @@ nve0_graph_trap_isr(struct nvc0_graph_priv *priv, u64 inst) | |||
101 | for (rop = 0; rop < priv->rop_nr; rop++) { | 103 | for (rop = 0; rop < priv->rop_nr; rop++) { |
102 | u32 statz = nv_rd32(priv, ROP_UNIT(rop, 0x070)); | 104 | u32 statz = nv_rd32(priv, ROP_UNIT(rop, 0x070)); |
103 | u32 statc = nv_rd32(priv, ROP_UNIT(rop, 0x144)); | 105 | u32 statc = nv_rd32(priv, ROP_UNIT(rop, 0x144)); |
104 | nv_error(priv, "ROP%d ch 0x%010llx 0x%08x 0x%08x\n", | 106 | nv_error(priv, "ROP%d ch %d [0x%010llx] 0x%08x 0x%08x\n", |
105 | rop, inst, statz, statc); | 107 | rop, chid, inst, statz, statc); |
106 | nv_wr32(priv, ROP_UNIT(rop, 0x070), 0xc0000000); | 108 | nv_wr32(priv, ROP_UNIT(rop, 0x070), 0xc0000000); |
107 | nv_wr32(priv, ROP_UNIT(rop, 0x144), 0xc0000000); | 109 | nv_wr32(priv, ROP_UNIT(rop, 0x144), 0xc0000000); |
108 | } | 110 | } |
@@ -111,7 +113,8 @@ nve0_graph_trap_isr(struct nvc0_graph_priv *priv, u64 inst) | |||
111 | } | 113 | } |
112 | 114 | ||
113 | if (trap) { | 115 | if (trap) { |
114 | nv_error(priv, "TRAP ch 0x%010llx 0x%08x\n", inst, trap); | 116 | nv_error(priv, "TRAP ch %d [0x%010llx] 0x%08x\n", |
117 | chid, inst, trap); | ||
115 | nv_wr32(priv, 0x400108, trap); | 118 | nv_wr32(priv, 0x400108, trap); |
116 | } | 119 | } |
117 | } | 120 | } |
@@ -119,10 +122,12 @@ nve0_graph_trap_isr(struct nvc0_graph_priv *priv, u64 inst) | |||
119 | static void | 122 | static void |
120 | nve0_graph_intr(struct nouveau_subdev *subdev) | 123 | nve0_graph_intr(struct nouveau_subdev *subdev) |
121 | { | 124 | { |
122 | struct nvc0_graph_priv *priv = (void *)subdev; | 125 | struct nouveau_fifo *pfifo = nouveau_fifo(subdev); |
123 | struct nouveau_engine *engine = nv_engine(subdev); | 126 | struct nouveau_engine *engine = nv_engine(subdev); |
124 | struct nouveau_handle *handle = NULL; | 127 | struct nouveau_object *engctx; |
125 | u64 inst = (u64)(nv_rd32(priv, 0x409b00) & 0x0fffffff) << 12; | 128 | struct nouveau_handle *handle; |
129 | struct nvc0_graph_priv *priv = (void *)subdev; | ||
130 | u64 inst = nv_rd32(priv, 0x409b00) & 0x0fffffff; | ||
126 | u32 stat = nv_rd32(priv, 0x400100); | 131 | u32 stat = nv_rd32(priv, 0x400100); |
127 | u32 addr = nv_rd32(priv, 0x400704); | 132 | u32 addr = nv_rd32(priv, 0x400704); |
128 | u32 mthd = (addr & 0x00003ffc); | 133 | u32 mthd = (addr & 0x00003ffc); |
@@ -130,24 +135,28 @@ nve0_graph_intr(struct nouveau_subdev *subdev) | |||
130 | u32 data = nv_rd32(priv, 0x400708); | 135 | u32 data = nv_rd32(priv, 0x400708); |
131 | u32 code = nv_rd32(priv, 0x400110); | 136 | u32 code = nv_rd32(priv, 0x400110); |
132 | u32 class = nv_rd32(priv, 0x404200 + (subc * 4)); | 137 | u32 class = nv_rd32(priv, 0x404200 + (subc * 4)); |
138 | int chid; | ||
139 | |||
140 | engctx = nouveau_engctx_get(engine, inst); | ||
141 | chid = pfifo->chid(pfifo, engctx); | ||
133 | 142 | ||
134 | if (stat & 0x00000010) { | 143 | if (stat & 0x00000010) { |
135 | handle = nouveau_engctx_lookup_class(engine, inst, class); | 144 | handle = nouveau_handle_get_class(engctx, class); |
136 | if (!handle || nv_call(handle->object, mthd, data)) { | 145 | if (!handle || nv_call(handle->object, mthd, data)) { |
137 | nv_error(priv, "ILLEGAL_MTHD ch 0x%010llx " | 146 | nv_error(priv, "ILLEGAL_MTHD ch %d [0x%010llx] " |
138 | "subc %d class 0x%04x mthd 0x%04x " | 147 | "subc %d class 0x%04x mthd 0x%04x " |
139 | "data 0x%08x\n", | 148 | "data 0x%08x\n", |
140 | inst, subc, class, mthd, data); | 149 | chid, inst, subc, class, mthd, data); |
141 | } | 150 | } |
142 | nouveau_engctx_handle_put(handle); | 151 | nouveau_handle_put(handle); |
143 | nv_wr32(priv, 0x400100, 0x00000010); | 152 | nv_wr32(priv, 0x400100, 0x00000010); |
144 | stat &= ~0x00000010; | 153 | stat &= ~0x00000010; |
145 | } | 154 | } |
146 | 155 | ||
147 | if (stat & 0x00000020) { | 156 | if (stat & 0x00000020) { |
148 | nv_error(priv, "ILLEGAL_CLASS ch 0x%010llx subc %d " | 157 | nv_error(priv, "ILLEGAL_CLASS ch %d [0x%010llx] subc %d " |
149 | "class 0x%04x mthd 0x%04x data 0x%08x\n", | 158 | "class 0x%04x mthd 0x%04x data 0x%08x\n", |
150 | inst, subc, class, mthd, data); | 159 | chid, inst, subc, class, mthd, data); |
151 | nv_wr32(priv, 0x400100, 0x00000020); | 160 | nv_wr32(priv, 0x400100, 0x00000020); |
152 | stat &= ~0x00000020; | 161 | stat &= ~0x00000020; |
153 | } | 162 | } |
@@ -155,15 +164,15 @@ nve0_graph_intr(struct nouveau_subdev *subdev) | |||
155 | if (stat & 0x00100000) { | 164 | if (stat & 0x00100000) { |
156 | nv_error(priv, "DATA_ERROR ["); | 165 | nv_error(priv, "DATA_ERROR ["); |
157 | nouveau_enum_print(nv50_data_error_names, code); | 166 | nouveau_enum_print(nv50_data_error_names, code); |
158 | printk("] ch 0x%010llx subc %d class 0x%04x " | 167 | printk("] ch %d [0x%010llx] subc %d class 0x%04x " |
159 | "mthd 0x%04x data 0x%08x\n", | 168 | "mthd 0x%04x data 0x%08x\n", |
160 | inst, subc, class, mthd, data); | 169 | chid, inst, subc, class, mthd, data); |
161 | nv_wr32(priv, 0x400100, 0x00100000); | 170 | nv_wr32(priv, 0x400100, 0x00100000); |
162 | stat &= ~0x00100000; | 171 | stat &= ~0x00100000; |
163 | } | 172 | } |
164 | 173 | ||
165 | if (stat & 0x00200000) { | 174 | if (stat & 0x00200000) { |
166 | nve0_graph_trap_isr(priv, inst); | 175 | nve0_graph_trap_isr(priv, chid, inst); |
167 | nv_wr32(priv, 0x400100, 0x00200000); | 176 | nv_wr32(priv, 0x400100, 0x00200000); |
168 | stat &= ~0x00200000; | 177 | stat &= ~0x00200000; |
169 | } | 178 | } |
@@ -180,6 +189,7 @@ nve0_graph_intr(struct nouveau_subdev *subdev) | |||
180 | } | 189 | } |
181 | 190 | ||
182 | nv_wr32(priv, 0x400500, 0x00010001); | 191 | nv_wr32(priv, 0x400500, 0x00010001); |
192 | nouveau_engctx_put(engctx); | ||
183 | } | 193 | } |
184 | 194 | ||
185 | static int | 195 | static int |
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c index 7a1bc7641b58..9adcefc275fb 100644 --- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c +++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c | |||
@@ -26,13 +26,14 @@ | |||
26 | #include <core/class.h> | 26 | #include <core/class.h> |
27 | #include <core/engctx.h> | 27 | #include <core/engctx.h> |
28 | #include <core/handle.h> | 28 | #include <core/handle.h> |
29 | #include <core/engine/graph/nv40.h> | ||
30 | 29 | ||
31 | #include <subdev/fb.h> | 30 | #include <subdev/fb.h> |
32 | #include <subdev/timer.h> | 31 | #include <subdev/timer.h> |
33 | #include <subdev/instmem.h> | 32 | #include <subdev/instmem.h> |
34 | 33 | ||
34 | #include <engine/fifo.h> | ||
35 | #include <engine/mpeg.h> | 35 | #include <engine/mpeg.h> |
36 | #include <engine/graph/nv40.h> | ||
36 | 37 | ||
37 | struct nv31_mpeg_priv { | 38 | struct nv31_mpeg_priv { |
38 | struct nouveau_mpeg base; | 39 | struct nouveau_mpeg base; |
@@ -195,30 +196,34 @@ nv31_mpeg_tile_prog(struct nouveau_engine *engine, int i) | |||
195 | void | 196 | void |
196 | nv31_mpeg_intr(struct nouveau_subdev *subdev) | 197 | nv31_mpeg_intr(struct nouveau_subdev *subdev) |
197 | { | 198 | { |
198 | struct nv31_mpeg_priv *priv = (void *)subdev; | 199 | struct nouveau_fifo *pfifo = nouveau_fifo(subdev); |
199 | struct nouveau_engine *engine = nv_engine(subdev); | 200 | struct nouveau_engine *engine = nv_engine(subdev); |
200 | struct nouveau_handle *handle = NULL; | 201 | struct nouveau_object *engctx; |
201 | u32 inst = (nv_rd32(priv, 0x00b318) & 0x000fffff) << 4; | 202 | struct nouveau_handle *handle; |
203 | struct nv31_mpeg_priv *priv = (void *)subdev; | ||
204 | u32 inst = nv_rd32(priv, 0x00b318) & 0x000fffff; | ||
202 | u32 stat = nv_rd32(priv, 0x00b100); | 205 | u32 stat = nv_rd32(priv, 0x00b100); |
203 | u32 type = nv_rd32(priv, 0x00b230); | 206 | u32 type = nv_rd32(priv, 0x00b230); |
204 | u32 mthd = nv_rd32(priv, 0x00b234); | 207 | u32 mthd = nv_rd32(priv, 0x00b234); |
205 | u32 data = nv_rd32(priv, 0x00b238); | 208 | u32 data = nv_rd32(priv, 0x00b238); |
206 | u32 show = stat; | 209 | u32 show = stat; |
210 | int chid; | ||
211 | |||
212 | engctx = nouveau_engctx_get(engine, inst); | ||
213 | chid = pfifo->chid(pfifo, engctx); | ||
207 | 214 | ||
208 | if (stat & 0x01000000) { | 215 | if (stat & 0x01000000) { |
209 | /* happens on initial binding of the object */ | 216 | /* happens on initial binding of the object */ |
210 | if (handle && type == 0x00000020 && mthd == 0x0000) { | 217 | if (type == 0x00000020 && mthd == 0x0000) { |
211 | nv_mask(priv, 0x00b308, 0x00000000, 0x00000000); | 218 | nv_mask(priv, 0x00b308, 0x00000000, 0x00000000); |
212 | show &= ~0x01000000; | 219 | show &= ~0x01000000; |
213 | } | 220 | } |
214 | 221 | ||
215 | if (handle && type == 0x00000010) { | 222 | if (type == 0x00000010) { |
216 | handle = nouveau_engctx_lookup_class(engine, inst, 0x3174); | 223 | handle = nouveau_handle_get_class(engctx, 0x3174); |
217 | 224 | if (handle && !nv_call(handle->object, mthd, data)) | |
218 | if (handle && !nv_call(handle->object, mthd, data)) { | ||
219 | nouveau_engctx_handle_put(handle); | ||
220 | show &= ~0x01000000; | 225 | show &= ~0x01000000; |
221 | } | 226 | nouveau_handle_put(handle); |
222 | } | 227 | } |
223 | } | 228 | } |
224 | 229 | ||
@@ -227,8 +232,10 @@ nv31_mpeg_intr(struct nouveau_subdev *subdev) | |||
227 | 232 | ||
228 | if (show) { | 233 | if (show) { |
229 | nv_error(priv, "ch %d [0x%08x] 0x%08x 0x%08x 0x%08x 0x%08x\n", | 234 | nv_error(priv, "ch %d [0x%08x] 0x%08x 0x%08x 0x%08x 0x%08x\n", |
230 | inst, stat, type, mthd, data); | 235 | chid, inst << 4, stat, type, mthd, data); |
231 | } | 236 | } |
237 | |||
238 | nouveau_engctx_put(engctx); | ||
232 | } | 239 | } |
233 | 240 | ||
234 | static int | 241 | static int |
diff --git a/drivers/gpu/drm/nouveau/core/include/core/engctx.h b/drivers/gpu/drm/nouveau/core/include/core/engctx.h index 227b2c190f1c..8a947b6872eb 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/engctx.h +++ b/drivers/gpu/drm/nouveau/core/include/core/engctx.h | |||
@@ -13,6 +13,7 @@ struct nouveau_engctx { | |||
13 | struct nouveau_gpuobj base; | 13 | struct nouveau_gpuobj base; |
14 | struct nouveau_vma vma; | 14 | struct nouveau_vma vma; |
15 | struct list_head head; | 15 | struct list_head head; |
16 | unsigned long save; | ||
16 | u64 addr; | 17 | u64 addr; |
17 | }; | 18 | }; |
18 | 19 | ||
@@ -44,19 +45,7 @@ int _nouveau_engctx_fini(struct nouveau_object *, bool suspend); | |||
44 | #define _nouveau_engctx_rd32 _nouveau_gpuobj_rd32 | 45 | #define _nouveau_engctx_rd32 _nouveau_gpuobj_rd32 |
45 | #define _nouveau_engctx_wr32 _nouveau_gpuobj_wr32 | 46 | #define _nouveau_engctx_wr32 _nouveau_gpuobj_wr32 |
46 | 47 | ||
47 | struct nouveau_object * | 48 | struct nouveau_object *nouveau_engctx_get(struct nouveau_engine *, u64 addr); |
48 | nouveau_engctx_lookup(struct nouveau_engine *, u64 addr); | 49 | void nouveau_engctx_put(struct nouveau_object *); |
49 | |||
50 | struct nouveau_handle * | ||
51 | nouveau_engctx_lookup_class(struct nouveau_engine *, u64, u16); | ||
52 | |||
53 | struct nouveau_handle * | ||
54 | nouveau_engctx_lookup_vinst(struct nouveau_engine *, u64, u64); | ||
55 | |||
56 | struct nouveau_handle * | ||
57 | nouveau_engctx_lookup_cinst(struct nouveau_engine *, u64, u32); | ||
58 | |||
59 | void | ||
60 | nouveau_engctx_handle_put(struct nouveau_handle *); | ||
61 | 50 | ||
62 | #endif | 51 | #endif |
diff --git a/drivers/gpu/drm/nouveau/core/include/core/handle.h b/drivers/gpu/drm/nouveau/core/include/core/handle.h index fbfbe55a7884..363674cdf8ab 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/handle.h +++ b/drivers/gpu/drm/nouveau/core/include/core/handle.h | |||
@@ -23,4 +23,9 @@ int nouveau_handle_fini(struct nouveau_handle *, bool suspend); | |||
23 | struct nouveau_object * | 23 | struct nouveau_object * |
24 | nouveau_handle_ref(struct nouveau_object *, u32 name); | 24 | nouveau_handle_ref(struct nouveau_object *, u32 name); |
25 | 25 | ||
26 | struct nouveau_handle *nouveau_handle_get_class(struct nouveau_object *, u16); | ||
27 | struct nouveau_handle *nouveau_handle_get_vinst(struct nouveau_object *, u64); | ||
28 | struct nouveau_handle *nouveau_handle_get_cinst(struct nouveau_object *, u32); | ||
29 | void nouveau_handle_put(struct nouveau_handle *); | ||
30 | |||
26 | #endif | 31 | #endif |