]>
Commit | Line | Data |
---|---|---|
6ee73861 BS |
1 | /* |
2 | * Copyright (C) 2007 Ben Skeggs. | |
3 | * All Rights Reserved. | |
4 | * | |
5 | * Permission is hereby granted, free of charge, to any person obtaining | |
6 | * a copy of this software and associated documentation files (the | |
7 | * "Software"), to deal in the Software without restriction, including | |
8 | * without limitation the rights to use, copy, modify, merge, publish, | |
9 | * distribute, sublicense, and/or sell copies of the Software, and to | |
10 | * permit persons to whom the Software is furnished to do so, subject to | |
11 | * the following conditions: | |
12 | * | |
13 | * The above copyright notice and this permission notice (including the | |
14 | * next paragraph) shall be included in all copies or substantial | |
15 | * portions of the Software. | |
16 | * | |
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
20 | * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | |
21 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |
22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
23 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
24 | * | |
25 | */ | |
26 | ||
27 | #include "drmP.h" | |
28 | #include "drm.h" | |
29 | #include "nouveau_drv.h" | |
a8eaebc6 | 30 | #include "nouveau_ramht.h" |
6ee73861 | 31 | |
6ee73861 | 32 | static void |
ac94a343 | 33 | nv50_fifo_playlist_update(struct drm_device *dev) |
6ee73861 BS |
34 | { |
35 | struct drm_nouveau_private *dev_priv = dev->dev_private; | |
ac94a343 | 36 | struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; |
a8eaebc6 | 37 | struct nouveau_gpuobj *cur; |
6ee73861 BS |
38 | int i, nr; |
39 | ||
40 | NV_DEBUG(dev, "\n"); | |
41 | ||
ac94a343 BS |
42 | cur = pfifo->playlist[pfifo->cur_playlist]; |
43 | pfifo->cur_playlist = !pfifo->cur_playlist; | |
6ee73861 BS |
44 | |
45 | /* We never schedule channel 0 or 127 */ | |
6ee73861 | 46 | for (i = 1, nr = 0; i < 127; i++) { |
b3beb167 | 47 | if (dev_priv->fifos[i] && dev_priv->fifos[i]->ramfc) { |
a8eaebc6 | 48 | nv_wo32(cur, (nr * 4), i); |
b3beb167 BS |
49 | nr++; |
50 | } | |
6ee73861 | 51 | } |
f56cb86f | 52 | dev_priv->engine.instmem.flush(dev); |
6ee73861 | 53 | |
a8eaebc6 | 54 | nv_wr32(dev, 0x32f4, cur->vinst >> 12); |
6ee73861 BS |
55 | nv_wr32(dev, 0x32ec, nr); |
56 | nv_wr32(dev, 0x2500, 0x101); | |
57 | } | |
58 | ||
ac94a343 BS |
59 | static void |
60 | nv50_fifo_channel_enable(struct drm_device *dev, int channel) | |
6ee73861 BS |
61 | { |
62 | struct drm_nouveau_private *dev_priv = dev->dev_private; | |
63 | struct nouveau_channel *chan = dev_priv->fifos[channel]; | |
64 | uint32_t inst; | |
65 | ||
66 | NV_DEBUG(dev, "ch%d\n", channel); | |
67 | ||
ac94a343 | 68 | if (dev_priv->chipset == 0x50) |
a8eaebc6 | 69 | inst = chan->ramfc->vinst >> 12; |
6ee73861 | 70 | else |
a8eaebc6 | 71 | inst = chan->ramfc->vinst >> 8; |
6ee73861 | 72 | |
ac94a343 BS |
73 | nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel), inst | |
74 | NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED); | |
6ee73861 BS |
75 | } |
76 | ||
77 | static void | |
ac94a343 | 78 | nv50_fifo_channel_disable(struct drm_device *dev, int channel) |
6ee73861 BS |
79 | { |
80 | struct drm_nouveau_private *dev_priv = dev->dev_private; | |
81 | uint32_t inst; | |
82 | ||
ac94a343 | 83 | NV_DEBUG(dev, "ch%d\n", channel); |
6ee73861 | 84 | |
ac94a343 | 85 | if (dev_priv->chipset == 0x50) |
6ee73861 BS |
86 | inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80; |
87 | else | |
88 | inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84; | |
89 | nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel), inst); | |
6ee73861 BS |
90 | } |
91 | ||
92 | static void | |
93 | nv50_fifo_init_reset(struct drm_device *dev) | |
94 | { | |
95 | uint32_t pmc_e = NV_PMC_ENABLE_PFIFO; | |
96 | ||
97 | NV_DEBUG(dev, "\n"); | |
98 | ||
99 | nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & ~pmc_e); | |
100 | nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | pmc_e); | |
101 | } | |
102 | ||
103 | static void | |
104 | nv50_fifo_init_intr(struct drm_device *dev) | |
105 | { | |
106 | NV_DEBUG(dev, "\n"); | |
107 | ||
108 | nv_wr32(dev, NV03_PFIFO_INTR_0, 0xFFFFFFFF); | |
109 | nv_wr32(dev, NV03_PFIFO_INTR_EN_0, 0xFFFFFFFF); | |
110 | } | |
111 | ||
112 | static void | |
113 | nv50_fifo_init_context_table(struct drm_device *dev) | |
114 | { | |
115 | struct drm_nouveau_private *dev_priv = dev->dev_private; | |
116 | int i; | |
117 | ||
118 | NV_DEBUG(dev, "\n"); | |
119 | ||
120 | for (i = 0; i < NV50_PFIFO_CTX_TABLE__SIZE; i++) { | |
121 | if (dev_priv->fifos[i]) | |
ac94a343 | 122 | nv50_fifo_channel_enable(dev, i); |
6ee73861 | 123 | else |
ac94a343 | 124 | nv50_fifo_channel_disable(dev, i); |
6ee73861 BS |
125 | } |
126 | ||
ac94a343 | 127 | nv50_fifo_playlist_update(dev); |
6ee73861 BS |
128 | } |
129 | ||
130 | static void | |
131 | nv50_fifo_init_regs__nv(struct drm_device *dev) | |
132 | { | |
133 | NV_DEBUG(dev, "\n"); | |
134 | ||
135 | nv_wr32(dev, 0x250c, 0x6f3cfc34); | |
136 | } | |
137 | ||
138 | static void | |
139 | nv50_fifo_init_regs(struct drm_device *dev) | |
140 | { | |
141 | NV_DEBUG(dev, "\n"); | |
142 | ||
143 | nv_wr32(dev, 0x2500, 0); | |
144 | nv_wr32(dev, 0x3250, 0); | |
145 | nv_wr32(dev, 0x3220, 0); | |
146 | nv_wr32(dev, 0x3204, 0); | |
147 | nv_wr32(dev, 0x3210, 0); | |
148 | nv_wr32(dev, 0x3270, 0); | |
149 | ||
150 | /* Enable dummy channels setup by nv50_instmem.c */ | |
ac94a343 BS |
151 | nv50_fifo_channel_enable(dev, 0); |
152 | nv50_fifo_channel_enable(dev, 127); | |
6ee73861 BS |
153 | } |
154 | ||
155 | int | |
156 | nv50_fifo_init(struct drm_device *dev) | |
157 | { | |
158 | struct drm_nouveau_private *dev_priv = dev->dev_private; | |
ac94a343 | 159 | struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; |
6ee73861 BS |
160 | int ret; |
161 | ||
162 | NV_DEBUG(dev, "\n"); | |
163 | ||
ac94a343 BS |
164 | if (pfifo->playlist[0]) { |
165 | pfifo->cur_playlist = !pfifo->cur_playlist; | |
6ee73861 BS |
166 | goto just_reset; |
167 | } | |
168 | ||
a8eaebc6 BS |
169 | ret = nouveau_gpuobj_new(dev, NULL, 128*4, 0x1000, |
170 | NVOBJ_FLAG_ZERO_ALLOC, | |
171 | &pfifo->playlist[0]); | |
6ee73861 | 172 | if (ret) { |
ac94a343 | 173 | NV_ERROR(dev, "error creating playlist 0: %d\n", ret); |
6ee73861 BS |
174 | return ret; |
175 | } | |
176 | ||
a8eaebc6 BS |
177 | ret = nouveau_gpuobj_new(dev, NULL, 128*4, 0x1000, |
178 | NVOBJ_FLAG_ZERO_ALLOC, | |
179 | &pfifo->playlist[1]); | |
6ee73861 | 180 | if (ret) { |
a8eaebc6 | 181 | nouveau_gpuobj_ref(NULL, &pfifo->playlist[0]); |
ac94a343 | 182 | NV_ERROR(dev, "error creating playlist 1: %d\n", ret); |
6ee73861 BS |
183 | return ret; |
184 | } | |
185 | ||
186 | just_reset: | |
187 | nv50_fifo_init_reset(dev); | |
188 | nv50_fifo_init_intr(dev); | |
189 | nv50_fifo_init_context_table(dev); | |
190 | nv50_fifo_init_regs__nv(dev); | |
191 | nv50_fifo_init_regs(dev); | |
192 | dev_priv->engine.fifo.enable(dev); | |
193 | dev_priv->engine.fifo.reassign(dev, true); | |
194 | ||
195 | return 0; | |
196 | } | |
197 | ||
198 | void | |
199 | nv50_fifo_takedown(struct drm_device *dev) | |
200 | { | |
201 | struct drm_nouveau_private *dev_priv = dev->dev_private; | |
ac94a343 | 202 | struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; |
6ee73861 BS |
203 | |
204 | NV_DEBUG(dev, "\n"); | |
205 | ||
ac94a343 | 206 | if (!pfifo->playlist[0]) |
6ee73861 BS |
207 | return; |
208 | ||
a8eaebc6 BS |
209 | nouveau_gpuobj_ref(NULL, &pfifo->playlist[0]); |
210 | nouveau_gpuobj_ref(NULL, &pfifo->playlist[1]); | |
6ee73861 BS |
211 | } |
212 | ||
213 | int | |
214 | nv50_fifo_channel_id(struct drm_device *dev) | |
215 | { | |
216 | return nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH1) & | |
217 | NV50_PFIFO_CACHE1_PUSH1_CHID_MASK; | |
218 | } | |
219 | ||
220 | int | |
221 | nv50_fifo_create_context(struct nouveau_channel *chan) | |
222 | { | |
223 | struct drm_device *dev = chan->dev; | |
224 | struct drm_nouveau_private *dev_priv = dev->dev_private; | |
225 | struct nouveau_gpuobj *ramfc = NULL; | |
ff9e5279 | 226 | unsigned long flags; |
6ee73861 BS |
227 | int ret; |
228 | ||
229 | NV_DEBUG(dev, "ch%d\n", chan->id); | |
230 | ||
ac94a343 | 231 | if (dev_priv->chipset == 0x50) { |
a8eaebc6 BS |
232 | ret = nouveau_gpuobj_new_fake(dev, chan->ramin->pinst, |
233 | chan->ramin->vinst, 0x100, | |
de3a6c0a | 234 | NVOBJ_FLAG_ZERO_ALLOC | |
a8eaebc6 | 235 | NVOBJ_FLAG_ZERO_FREE, |
6ee73861 BS |
236 | &chan->ramfc); |
237 | if (ret) | |
238 | return ret; | |
239 | ||
a8eaebc6 BS |
240 | ret = nouveau_gpuobj_new_fake(dev, chan->ramin->pinst + 0x0400, |
241 | chan->ramin->vinst + 0x0400, | |
242 | 4096, 0, &chan->cache); | |
6ee73861 BS |
243 | if (ret) |
244 | return ret; | |
245 | } else { | |
a8eaebc6 BS |
246 | ret = nouveau_gpuobj_new(dev, chan, 0x100, 256, |
247 | NVOBJ_FLAG_ZERO_ALLOC | | |
248 | NVOBJ_FLAG_ZERO_FREE, &chan->ramfc); | |
6ee73861 BS |
249 | if (ret) |
250 | return ret; | |
6ee73861 | 251 | |
a8eaebc6 BS |
252 | ret = nouveau_gpuobj_new(dev, chan, 4096, 1024, |
253 | 0, &chan->cache); | |
6ee73861 BS |
254 | if (ret) |
255 | return ret; | |
256 | } | |
a8eaebc6 | 257 | ramfc = chan->ramfc; |
6ee73861 | 258 | |
ff9e5279 MM |
259 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); |
260 | ||
a8eaebc6 | 261 | nv_wo32(ramfc, 0x48, chan->pushbuf->cinst >> 4); |
e05c5a31 | 262 | nv_wo32(ramfc, 0x80, ((chan->ramht->bits - 9) << 27) | |
b3beb167 | 263 | (4 << 24) /* SEARCH_FULL */ | |
a8eaebc6 | 264 | (chan->ramht->gpuobj->cinst >> 4)); |
b3beb167 BS |
265 | nv_wo32(ramfc, 0x44, 0x2101ffff); |
266 | nv_wo32(ramfc, 0x60, 0x7fffffff); | |
267 | nv_wo32(ramfc, 0x40, 0x00000000); | |
268 | nv_wo32(ramfc, 0x7c, 0x30000001); | |
269 | nv_wo32(ramfc, 0x78, 0x00000000); | |
270 | nv_wo32(ramfc, 0x3c, 0x403f6078); | |
271 | nv_wo32(ramfc, 0x50, chan->pushbuf_base + chan->dma.ib_base * 4); | |
272 | nv_wo32(ramfc, 0x54, drm_order(chan->dma.ib_max + 1) << 16); | |
6ee73861 | 273 | |
ac94a343 | 274 | if (dev_priv->chipset != 0x50) { |
a8eaebc6 BS |
275 | nv_wo32(chan->ramin, 0, chan->id); |
276 | nv_wo32(chan->ramin, 4, chan->ramfc->vinst >> 8); | |
6ee73861 | 277 | |
a8eaebc6 BS |
278 | nv_wo32(ramfc, 0x88, chan->cache->vinst >> 10); |
279 | nv_wo32(ramfc, 0x98, chan->ramin->vinst >> 12); | |
6ee73861 BS |
280 | } |
281 | ||
f56cb86f | 282 | dev_priv->engine.instmem.flush(dev); |
6ee73861 | 283 | |
ac94a343 BS |
284 | nv50_fifo_channel_enable(dev, chan->id); |
285 | nv50_fifo_playlist_update(dev); | |
ff9e5279 | 286 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); |
6ee73861 BS |
287 | return 0; |
288 | } | |
289 | ||
290 | void | |
291 | nv50_fifo_destroy_context(struct nouveau_channel *chan) | |
292 | { | |
293 | struct drm_device *dev = chan->dev; | |
a8eaebc6 | 294 | struct nouveau_gpuobj *ramfc = NULL; |
6ee73861 BS |
295 | |
296 | NV_DEBUG(dev, "ch%d\n", chan->id); | |
297 | ||
a87ff62a | 298 | /* This will ensure the channel is seen as disabled. */ |
a8eaebc6 BS |
299 | nouveau_gpuobj_ref(chan->ramfc, &ramfc); |
300 | nouveau_gpuobj_ref(NULL, &chan->ramfc); | |
ac94a343 | 301 | nv50_fifo_channel_disable(dev, chan->id); |
6ee73861 BS |
302 | |
303 | /* Dummy channel, also used on ch 127 */ | |
304 | if (chan->id == 0) | |
ac94a343 BS |
305 | nv50_fifo_channel_disable(dev, 127); |
306 | nv50_fifo_playlist_update(dev); | |
a87ff62a | 307 | |
a8eaebc6 BS |
308 | nouveau_gpuobj_ref(NULL, &ramfc); |
309 | nouveau_gpuobj_ref(NULL, &chan->cache); | |
6ee73861 BS |
310 | } |
311 | ||
312 | int | |
313 | nv50_fifo_load_context(struct nouveau_channel *chan) | |
314 | { | |
315 | struct drm_device *dev = chan->dev; | |
316 | struct drm_nouveau_private *dev_priv = dev->dev_private; | |
a8eaebc6 BS |
317 | struct nouveau_gpuobj *ramfc = chan->ramfc; |
318 | struct nouveau_gpuobj *cache = chan->cache; | |
6ee73861 BS |
319 | int ptr, cnt; |
320 | ||
321 | NV_DEBUG(dev, "ch%d\n", chan->id); | |
322 | ||
b3beb167 BS |
323 | nv_wr32(dev, 0x3330, nv_ro32(ramfc, 0x00)); |
324 | nv_wr32(dev, 0x3334, nv_ro32(ramfc, 0x04)); | |
325 | nv_wr32(dev, 0x3240, nv_ro32(ramfc, 0x08)); | |
326 | nv_wr32(dev, 0x3320, nv_ro32(ramfc, 0x0c)); | |
327 | nv_wr32(dev, 0x3244, nv_ro32(ramfc, 0x10)); | |
328 | nv_wr32(dev, 0x3328, nv_ro32(ramfc, 0x14)); | |
329 | nv_wr32(dev, 0x3368, nv_ro32(ramfc, 0x18)); | |
330 | nv_wr32(dev, 0x336c, nv_ro32(ramfc, 0x1c)); | |
331 | nv_wr32(dev, 0x3370, nv_ro32(ramfc, 0x20)); | |
332 | nv_wr32(dev, 0x3374, nv_ro32(ramfc, 0x24)); | |
333 | nv_wr32(dev, 0x3378, nv_ro32(ramfc, 0x28)); | |
334 | nv_wr32(dev, 0x337c, nv_ro32(ramfc, 0x2c)); | |
335 | nv_wr32(dev, 0x3228, nv_ro32(ramfc, 0x30)); | |
336 | nv_wr32(dev, 0x3364, nv_ro32(ramfc, 0x34)); | |
337 | nv_wr32(dev, 0x32a0, nv_ro32(ramfc, 0x38)); | |
338 | nv_wr32(dev, 0x3224, nv_ro32(ramfc, 0x3c)); | |
339 | nv_wr32(dev, 0x324c, nv_ro32(ramfc, 0x40)); | |
340 | nv_wr32(dev, 0x2044, nv_ro32(ramfc, 0x44)); | |
341 | nv_wr32(dev, 0x322c, nv_ro32(ramfc, 0x48)); | |
342 | nv_wr32(dev, 0x3234, nv_ro32(ramfc, 0x4c)); | |
343 | nv_wr32(dev, 0x3340, nv_ro32(ramfc, 0x50)); | |
344 | nv_wr32(dev, 0x3344, nv_ro32(ramfc, 0x54)); | |
345 | nv_wr32(dev, 0x3280, nv_ro32(ramfc, 0x58)); | |
346 | nv_wr32(dev, 0x3254, nv_ro32(ramfc, 0x5c)); | |
347 | nv_wr32(dev, 0x3260, nv_ro32(ramfc, 0x60)); | |
348 | nv_wr32(dev, 0x3264, nv_ro32(ramfc, 0x64)); | |
349 | nv_wr32(dev, 0x3268, nv_ro32(ramfc, 0x68)); | |
350 | nv_wr32(dev, 0x326c, nv_ro32(ramfc, 0x6c)); | |
351 | nv_wr32(dev, 0x32e4, nv_ro32(ramfc, 0x70)); | |
352 | nv_wr32(dev, 0x3248, nv_ro32(ramfc, 0x74)); | |
353 | nv_wr32(dev, 0x2088, nv_ro32(ramfc, 0x78)); | |
354 | nv_wr32(dev, 0x2058, nv_ro32(ramfc, 0x7c)); | |
355 | nv_wr32(dev, 0x2210, nv_ro32(ramfc, 0x80)); | |
356 | ||
357 | cnt = nv_ro32(ramfc, 0x84); | |
6ee73861 BS |
358 | for (ptr = 0; ptr < cnt; ptr++) { |
359 | nv_wr32(dev, NV40_PFIFO_CACHE1_METHOD(ptr), | |
b3beb167 | 360 | nv_ro32(cache, (ptr * 8) + 0)); |
6ee73861 | 361 | nv_wr32(dev, NV40_PFIFO_CACHE1_DATA(ptr), |
b3beb167 | 362 | nv_ro32(cache, (ptr * 8) + 4)); |
6ee73861 | 363 | } |
7fb8ec8e BS |
364 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, cnt << 2); |
365 | nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); | |
6ee73861 BS |
366 | |
367 | /* guessing that all the 0x34xx regs aren't on NV50 */ | |
ac94a343 | 368 | if (dev_priv->chipset != 0x50) { |
b3beb167 BS |
369 | nv_wr32(dev, 0x340c, nv_ro32(ramfc, 0x88)); |
370 | nv_wr32(dev, 0x3400, nv_ro32(ramfc, 0x8c)); | |
371 | nv_wr32(dev, 0x3404, nv_ro32(ramfc, 0x90)); | |
372 | nv_wr32(dev, 0x3408, nv_ro32(ramfc, 0x94)); | |
373 | nv_wr32(dev, 0x3410, nv_ro32(ramfc, 0x98)); | |
6ee73861 BS |
374 | } |
375 | ||
6ee73861 BS |
376 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, chan->id | (1<<16)); |
377 | return 0; | |
378 | } | |
379 | ||
380 | int | |
381 | nv50_fifo_unload_context(struct drm_device *dev) | |
382 | { | |
383 | struct drm_nouveau_private *dev_priv = dev->dev_private; | |
384 | struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; | |
385 | struct nouveau_gpuobj *ramfc, *cache; | |
386 | struct nouveau_channel *chan = NULL; | |
387 | int chid, get, put, ptr; | |
388 | ||
389 | NV_DEBUG(dev, "\n"); | |
390 | ||
391 | chid = pfifo->channel_id(dev); | |
3c8868d3 | 392 | if (chid < 1 || chid >= dev_priv->engine.fifo.channels - 1) |
6ee73861 BS |
393 | return 0; |
394 | ||
395 | chan = dev_priv->fifos[chid]; | |
396 | if (!chan) { | |
397 | NV_ERROR(dev, "Inactive channel on PFIFO: %d\n", chid); | |
398 | return -EINVAL; | |
399 | } | |
400 | NV_DEBUG(dev, "ch%d\n", chan->id); | |
a8eaebc6 BS |
401 | ramfc = chan->ramfc; |
402 | cache = chan->cache; | |
6ee73861 | 403 | |
b3beb167 BS |
404 | nv_wo32(ramfc, 0x00, nv_rd32(dev, 0x3330)); |
405 | nv_wo32(ramfc, 0x04, nv_rd32(dev, 0x3334)); | |
406 | nv_wo32(ramfc, 0x08, nv_rd32(dev, 0x3240)); | |
407 | nv_wo32(ramfc, 0x0c, nv_rd32(dev, 0x3320)); | |
408 | nv_wo32(ramfc, 0x10, nv_rd32(dev, 0x3244)); | |
409 | nv_wo32(ramfc, 0x14, nv_rd32(dev, 0x3328)); | |
410 | nv_wo32(ramfc, 0x18, nv_rd32(dev, 0x3368)); | |
411 | nv_wo32(ramfc, 0x1c, nv_rd32(dev, 0x336c)); | |
412 | nv_wo32(ramfc, 0x20, nv_rd32(dev, 0x3370)); | |
413 | nv_wo32(ramfc, 0x24, nv_rd32(dev, 0x3374)); | |
414 | nv_wo32(ramfc, 0x28, nv_rd32(dev, 0x3378)); | |
415 | nv_wo32(ramfc, 0x2c, nv_rd32(dev, 0x337c)); | |
416 | nv_wo32(ramfc, 0x30, nv_rd32(dev, 0x3228)); | |
417 | nv_wo32(ramfc, 0x34, nv_rd32(dev, 0x3364)); | |
418 | nv_wo32(ramfc, 0x38, nv_rd32(dev, 0x32a0)); | |
419 | nv_wo32(ramfc, 0x3c, nv_rd32(dev, 0x3224)); | |
420 | nv_wo32(ramfc, 0x40, nv_rd32(dev, 0x324c)); | |
421 | nv_wo32(ramfc, 0x44, nv_rd32(dev, 0x2044)); | |
422 | nv_wo32(ramfc, 0x48, nv_rd32(dev, 0x322c)); | |
423 | nv_wo32(ramfc, 0x4c, nv_rd32(dev, 0x3234)); | |
424 | nv_wo32(ramfc, 0x50, nv_rd32(dev, 0x3340)); | |
425 | nv_wo32(ramfc, 0x54, nv_rd32(dev, 0x3344)); | |
426 | nv_wo32(ramfc, 0x58, nv_rd32(dev, 0x3280)); | |
427 | nv_wo32(ramfc, 0x5c, nv_rd32(dev, 0x3254)); | |
428 | nv_wo32(ramfc, 0x60, nv_rd32(dev, 0x3260)); | |
429 | nv_wo32(ramfc, 0x64, nv_rd32(dev, 0x3264)); | |
430 | nv_wo32(ramfc, 0x68, nv_rd32(dev, 0x3268)); | |
431 | nv_wo32(ramfc, 0x6c, nv_rd32(dev, 0x326c)); | |
432 | nv_wo32(ramfc, 0x70, nv_rd32(dev, 0x32e4)); | |
433 | nv_wo32(ramfc, 0x74, nv_rd32(dev, 0x3248)); | |
434 | nv_wo32(ramfc, 0x78, nv_rd32(dev, 0x2088)); | |
435 | nv_wo32(ramfc, 0x7c, nv_rd32(dev, 0x2058)); | |
436 | nv_wo32(ramfc, 0x80, nv_rd32(dev, 0x2210)); | |
6ee73861 BS |
437 | |
438 | put = (nv_rd32(dev, NV03_PFIFO_CACHE1_PUT) & 0x7ff) >> 2; | |
439 | get = (nv_rd32(dev, NV03_PFIFO_CACHE1_GET) & 0x7ff) >> 2; | |
440 | ptr = 0; | |
441 | while (put != get) { | |
b3beb167 BS |
442 | nv_wo32(cache, ptr + 0, |
443 | nv_rd32(dev, NV40_PFIFO_CACHE1_METHOD(get))); | |
444 | nv_wo32(cache, ptr + 4, | |
445 | nv_rd32(dev, NV40_PFIFO_CACHE1_DATA(get))); | |
6ee73861 | 446 | get = (get + 1) & 0x1ff; |
b3beb167 | 447 | ptr += 8; |
6ee73861 BS |
448 | } |
449 | ||
450 | /* guessing that all the 0x34xx regs aren't on NV50 */ | |
ac94a343 | 451 | if (dev_priv->chipset != 0x50) { |
b3beb167 BS |
452 | nv_wo32(ramfc, 0x84, ptr >> 3); |
453 | nv_wo32(ramfc, 0x88, nv_rd32(dev, 0x340c)); | |
454 | nv_wo32(ramfc, 0x8c, nv_rd32(dev, 0x3400)); | |
455 | nv_wo32(ramfc, 0x90, nv_rd32(dev, 0x3404)); | |
456 | nv_wo32(ramfc, 0x94, nv_rd32(dev, 0x3408)); | |
457 | nv_wo32(ramfc, 0x98, nv_rd32(dev, 0x3410)); | |
6ee73861 BS |
458 | } |
459 | ||
f56cb86f | 460 | dev_priv->engine.instmem.flush(dev); |
6ee73861 BS |
461 | |
462 | /*XXX: probably reload ch127 (NULL) state back too */ | |
463 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, 127); | |
464 | return 0; | |
465 | } | |
466 |