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" | |
30 | ||
6ee73861 | 31 | static void |
ac94a343 | 32 | nv50_fifo_playlist_update(struct drm_device *dev) |
6ee73861 BS |
33 | { |
34 | struct drm_nouveau_private *dev_priv = dev->dev_private; | |
ac94a343 | 35 | struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; |
6ee73861 BS |
36 | struct nouveau_gpuobj_ref *cur; |
37 | int i, nr; | |
38 | ||
39 | NV_DEBUG(dev, "\n"); | |
40 | ||
ac94a343 BS |
41 | cur = pfifo->playlist[pfifo->cur_playlist]; |
42 | pfifo->cur_playlist = !pfifo->cur_playlist; | |
6ee73861 BS |
43 | |
44 | /* We never schedule channel 0 or 127 */ | |
6ee73861 BS |
45 | for (i = 1, nr = 0; i < 127; i++) { |
46 | if (dev_priv->fifos[i] && dev_priv->fifos[i]->ramfc) | |
47 | nv_wo32(dev, cur->gpuobj, nr++, i); | |
48 | } | |
f56cb86f | 49 | dev_priv->engine.instmem.flush(dev); |
6ee73861 BS |
50 | |
51 | nv_wr32(dev, 0x32f4, cur->instance >> 12); | |
52 | nv_wr32(dev, 0x32ec, nr); | |
53 | nv_wr32(dev, 0x2500, 0x101); | |
54 | } | |
55 | ||
ac94a343 BS |
56 | static void |
57 | nv50_fifo_channel_enable(struct drm_device *dev, int channel) | |
6ee73861 BS |
58 | { |
59 | struct drm_nouveau_private *dev_priv = dev->dev_private; | |
60 | struct nouveau_channel *chan = dev_priv->fifos[channel]; | |
61 | uint32_t inst; | |
62 | ||
63 | NV_DEBUG(dev, "ch%d\n", channel); | |
64 | ||
ac94a343 | 65 | if (dev_priv->chipset == 0x50) |
6ee73861 BS |
66 | inst = chan->ramfc->instance >> 12; |
67 | else | |
68 | inst = chan->ramfc->instance >> 8; | |
6ee73861 | 69 | |
ac94a343 BS |
70 | nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel), inst | |
71 | NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED); | |
6ee73861 BS |
72 | } |
73 | ||
74 | static void | |
ac94a343 | 75 | nv50_fifo_channel_disable(struct drm_device *dev, int channel) |
6ee73861 BS |
76 | { |
77 | struct drm_nouveau_private *dev_priv = dev->dev_private; | |
78 | uint32_t inst; | |
79 | ||
ac94a343 | 80 | NV_DEBUG(dev, "ch%d\n", channel); |
6ee73861 | 81 | |
ac94a343 | 82 | if (dev_priv->chipset == 0x50) |
6ee73861 BS |
83 | inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80; |
84 | else | |
85 | inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84; | |
86 | nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel), inst); | |
6ee73861 BS |
87 | } |
88 | ||
89 | static void | |
90 | nv50_fifo_init_reset(struct drm_device *dev) | |
91 | { | |
92 | uint32_t pmc_e = NV_PMC_ENABLE_PFIFO; | |
93 | ||
94 | NV_DEBUG(dev, "\n"); | |
95 | ||
96 | nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & ~pmc_e); | |
97 | nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | pmc_e); | |
98 | } | |
99 | ||
100 | static void | |
101 | nv50_fifo_init_intr(struct drm_device *dev) | |
102 | { | |
103 | NV_DEBUG(dev, "\n"); | |
104 | ||
105 | nv_wr32(dev, NV03_PFIFO_INTR_0, 0xFFFFFFFF); | |
106 | nv_wr32(dev, NV03_PFIFO_INTR_EN_0, 0xFFFFFFFF); | |
107 | } | |
108 | ||
109 | static void | |
110 | nv50_fifo_init_context_table(struct drm_device *dev) | |
111 | { | |
112 | struct drm_nouveau_private *dev_priv = dev->dev_private; | |
113 | int i; | |
114 | ||
115 | NV_DEBUG(dev, "\n"); | |
116 | ||
117 | for (i = 0; i < NV50_PFIFO_CTX_TABLE__SIZE; i++) { | |
118 | if (dev_priv->fifos[i]) | |
ac94a343 | 119 | nv50_fifo_channel_enable(dev, i); |
6ee73861 | 120 | else |
ac94a343 | 121 | nv50_fifo_channel_disable(dev, i); |
6ee73861 BS |
122 | } |
123 | ||
ac94a343 | 124 | nv50_fifo_playlist_update(dev); |
6ee73861 BS |
125 | } |
126 | ||
127 | static void | |
128 | nv50_fifo_init_regs__nv(struct drm_device *dev) | |
129 | { | |
130 | NV_DEBUG(dev, "\n"); | |
131 | ||
132 | nv_wr32(dev, 0x250c, 0x6f3cfc34); | |
133 | } | |
134 | ||
135 | static void | |
136 | nv50_fifo_init_regs(struct drm_device *dev) | |
137 | { | |
138 | NV_DEBUG(dev, "\n"); | |
139 | ||
140 | nv_wr32(dev, 0x2500, 0); | |
141 | nv_wr32(dev, 0x3250, 0); | |
142 | nv_wr32(dev, 0x3220, 0); | |
143 | nv_wr32(dev, 0x3204, 0); | |
144 | nv_wr32(dev, 0x3210, 0); | |
145 | nv_wr32(dev, 0x3270, 0); | |
146 | ||
147 | /* Enable dummy channels setup by nv50_instmem.c */ | |
ac94a343 BS |
148 | nv50_fifo_channel_enable(dev, 0); |
149 | nv50_fifo_channel_enable(dev, 127); | |
6ee73861 BS |
150 | } |
151 | ||
152 | int | |
153 | nv50_fifo_init(struct drm_device *dev) | |
154 | { | |
155 | struct drm_nouveau_private *dev_priv = dev->dev_private; | |
ac94a343 | 156 | struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; |
6ee73861 BS |
157 | int ret; |
158 | ||
159 | NV_DEBUG(dev, "\n"); | |
160 | ||
ac94a343 BS |
161 | if (pfifo->playlist[0]) { |
162 | pfifo->cur_playlist = !pfifo->cur_playlist; | |
6ee73861 BS |
163 | goto just_reset; |
164 | } | |
165 | ||
6ee73861 | 166 | ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 128*4, 0x1000, |
ac94a343 BS |
167 | NVOBJ_FLAG_ZERO_ALLOC, |
168 | &pfifo->playlist[0]); | |
6ee73861 | 169 | if (ret) { |
ac94a343 | 170 | NV_ERROR(dev, "error creating playlist 0: %d\n", ret); |
6ee73861 BS |
171 | return ret; |
172 | } | |
173 | ||
174 | ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 128*4, 0x1000, | |
ac94a343 BS |
175 | NVOBJ_FLAG_ZERO_ALLOC, |
176 | &pfifo->playlist[1]); | |
6ee73861 | 177 | if (ret) { |
ac94a343 BS |
178 | nouveau_gpuobj_ref_del(dev, &pfifo->playlist[0]); |
179 | NV_ERROR(dev, "error creating playlist 1: %d\n", ret); | |
6ee73861 BS |
180 | return ret; |
181 | } | |
182 | ||
183 | just_reset: | |
184 | nv50_fifo_init_reset(dev); | |
185 | nv50_fifo_init_intr(dev); | |
186 | nv50_fifo_init_context_table(dev); | |
187 | nv50_fifo_init_regs__nv(dev); | |
188 | nv50_fifo_init_regs(dev); | |
189 | dev_priv->engine.fifo.enable(dev); | |
190 | dev_priv->engine.fifo.reassign(dev, true); | |
191 | ||
192 | return 0; | |
193 | } | |
194 | ||
195 | void | |
196 | nv50_fifo_takedown(struct drm_device *dev) | |
197 | { | |
198 | struct drm_nouveau_private *dev_priv = dev->dev_private; | |
ac94a343 | 199 | struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; |
6ee73861 BS |
200 | |
201 | NV_DEBUG(dev, "\n"); | |
202 | ||
ac94a343 | 203 | if (!pfifo->playlist[0]) |
6ee73861 BS |
204 | return; |
205 | ||
ac94a343 BS |
206 | nouveau_gpuobj_ref_del(dev, &pfifo->playlist[0]); |
207 | nouveau_gpuobj_ref_del(dev, &pfifo->playlist[1]); | |
6ee73861 BS |
208 | } |
209 | ||
210 | int | |
211 | nv50_fifo_channel_id(struct drm_device *dev) | |
212 | { | |
213 | return nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH1) & | |
214 | NV50_PFIFO_CACHE1_PUSH1_CHID_MASK; | |
215 | } | |
216 | ||
217 | int | |
218 | nv50_fifo_create_context(struct nouveau_channel *chan) | |
219 | { | |
220 | struct drm_device *dev = chan->dev; | |
221 | struct drm_nouveau_private *dev_priv = dev->dev_private; | |
222 | struct nouveau_gpuobj *ramfc = NULL; | |
ff9e5279 | 223 | unsigned long flags; |
6ee73861 BS |
224 | int ret; |
225 | ||
226 | NV_DEBUG(dev, "ch%d\n", chan->id); | |
227 | ||
ac94a343 | 228 | if (dev_priv->chipset == 0x50) { |
6ee73861 BS |
229 | uint32_t ramin_poffset = chan->ramin->gpuobj->im_pramin->start; |
230 | uint32_t ramin_voffset = chan->ramin->gpuobj->im_backing_start; | |
231 | ||
232 | ret = nouveau_gpuobj_new_fake(dev, ramin_poffset, ramin_voffset, | |
233 | 0x100, NVOBJ_FLAG_ZERO_ALLOC | | |
234 | NVOBJ_FLAG_ZERO_FREE, &ramfc, | |
235 | &chan->ramfc); | |
236 | if (ret) | |
237 | return ret; | |
238 | ||
239 | ret = nouveau_gpuobj_new_fake(dev, ramin_poffset + 0x0400, | |
240 | ramin_voffset + 0x0400, 4096, | |
241 | 0, NULL, &chan->cache); | |
242 | if (ret) | |
243 | return ret; | |
244 | } else { | |
245 | ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, 0x100, 256, | |
246 | NVOBJ_FLAG_ZERO_ALLOC | | |
247 | NVOBJ_FLAG_ZERO_FREE, | |
248 | &chan->ramfc); | |
249 | if (ret) | |
250 | return ret; | |
251 | ramfc = chan->ramfc->gpuobj; | |
252 | ||
134f248b | 253 | ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, 4096, 1024, |
6ee73861 BS |
254 | 0, &chan->cache); |
255 | if (ret) | |
256 | return ret; | |
257 | } | |
258 | ||
ff9e5279 MM |
259 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); |
260 | ||
6ee73861 | 261 | nv_wo32(dev, ramfc, 0x48/4, chan->pushbuf->instance >> 4); |
ca6adb8a BS |
262 | nv_wo32(dev, ramfc, 0x80/4, (0 << 27) /* 4KiB */ | |
263 | (4 << 24) /* SEARCH_FULL */ | | |
264 | (chan->ramht->instance >> 4)); | |
6ee73861 BS |
265 | nv_wo32(dev, ramfc, 0x44/4, 0x2101ffff); |
266 | nv_wo32(dev, ramfc, 0x60/4, 0x7fffffff); | |
267 | nv_wo32(dev, ramfc, 0x40/4, 0x00000000); | |
268 | nv_wo32(dev, ramfc, 0x7c/4, 0x30000001); | |
269 | nv_wo32(dev, ramfc, 0x78/4, 0x00000000); | |
9a391ad8 BS |
270 | nv_wo32(dev, ramfc, 0x3c/4, 0x403f6078); |
271 | nv_wo32(dev, ramfc, 0x50/4, chan->pushbuf_base + | |
272 | chan->dma.ib_base * 4); | |
273 | nv_wo32(dev, ramfc, 0x54/4, drm_order(chan->dma.ib_max + 1) << 16); | |
6ee73861 | 274 | |
ac94a343 | 275 | if (dev_priv->chipset != 0x50) { |
6ee73861 BS |
276 | nv_wo32(dev, chan->ramin->gpuobj, 0, chan->id); |
277 | nv_wo32(dev, chan->ramin->gpuobj, 1, | |
278 | chan->ramfc->instance >> 8); | |
279 | ||
280 | nv_wo32(dev, ramfc, 0x88/4, chan->cache->instance >> 10); | |
281 | nv_wo32(dev, ramfc, 0x98/4, chan->ramin->instance >> 12); | |
282 | } | |
283 | ||
f56cb86f | 284 | dev_priv->engine.instmem.flush(dev); |
6ee73861 | 285 | |
ac94a343 BS |
286 | nv50_fifo_channel_enable(dev, chan->id); |
287 | nv50_fifo_playlist_update(dev); | |
ff9e5279 | 288 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); |
6ee73861 BS |
289 | return 0; |
290 | } | |
291 | ||
292 | void | |
293 | nv50_fifo_destroy_context(struct nouveau_channel *chan) | |
294 | { | |
295 | struct drm_device *dev = chan->dev; | |
a87ff62a | 296 | struct nouveau_gpuobj_ref *ramfc = chan->ramfc; |
6ee73861 BS |
297 | |
298 | NV_DEBUG(dev, "ch%d\n", chan->id); | |
299 | ||
a87ff62a MM |
300 | /* This will ensure the channel is seen as disabled. */ |
301 | chan->ramfc = NULL; | |
ac94a343 | 302 | nv50_fifo_channel_disable(dev, chan->id); |
6ee73861 BS |
303 | |
304 | /* Dummy channel, also used on ch 127 */ | |
305 | if (chan->id == 0) | |
ac94a343 BS |
306 | nv50_fifo_channel_disable(dev, 127); |
307 | nv50_fifo_playlist_update(dev); | |
a87ff62a MM |
308 | |
309 | nouveau_gpuobj_ref_del(dev, &ramfc); | |
310 | nouveau_gpuobj_ref_del(dev, &chan->cache); | |
6ee73861 BS |
311 | } |
312 | ||
313 | int | |
314 | nv50_fifo_load_context(struct nouveau_channel *chan) | |
315 | { | |
316 | struct drm_device *dev = chan->dev; | |
317 | struct drm_nouveau_private *dev_priv = dev->dev_private; | |
318 | struct nouveau_gpuobj *ramfc = chan->ramfc->gpuobj; | |
319 | struct nouveau_gpuobj *cache = chan->cache->gpuobj; | |
320 | int ptr, cnt; | |
321 | ||
322 | NV_DEBUG(dev, "ch%d\n", chan->id); | |
323 | ||
6ee73861 BS |
324 | nv_wr32(dev, 0x3330, nv_ro32(dev, ramfc, 0x00/4)); |
325 | nv_wr32(dev, 0x3334, nv_ro32(dev, ramfc, 0x04/4)); | |
326 | nv_wr32(dev, 0x3240, nv_ro32(dev, ramfc, 0x08/4)); | |
327 | nv_wr32(dev, 0x3320, nv_ro32(dev, ramfc, 0x0c/4)); | |
328 | nv_wr32(dev, 0x3244, nv_ro32(dev, ramfc, 0x10/4)); | |
329 | nv_wr32(dev, 0x3328, nv_ro32(dev, ramfc, 0x14/4)); | |
330 | nv_wr32(dev, 0x3368, nv_ro32(dev, ramfc, 0x18/4)); | |
331 | nv_wr32(dev, 0x336c, nv_ro32(dev, ramfc, 0x1c/4)); | |
332 | nv_wr32(dev, 0x3370, nv_ro32(dev, ramfc, 0x20/4)); | |
333 | nv_wr32(dev, 0x3374, nv_ro32(dev, ramfc, 0x24/4)); | |
334 | nv_wr32(dev, 0x3378, nv_ro32(dev, ramfc, 0x28/4)); | |
335 | nv_wr32(dev, 0x337c, nv_ro32(dev, ramfc, 0x2c/4)); | |
336 | nv_wr32(dev, 0x3228, nv_ro32(dev, ramfc, 0x30/4)); | |
337 | nv_wr32(dev, 0x3364, nv_ro32(dev, ramfc, 0x34/4)); | |
338 | nv_wr32(dev, 0x32a0, nv_ro32(dev, ramfc, 0x38/4)); | |
339 | nv_wr32(dev, 0x3224, nv_ro32(dev, ramfc, 0x3c/4)); | |
340 | nv_wr32(dev, 0x324c, nv_ro32(dev, ramfc, 0x40/4)); | |
341 | nv_wr32(dev, 0x2044, nv_ro32(dev, ramfc, 0x44/4)); | |
342 | nv_wr32(dev, 0x322c, nv_ro32(dev, ramfc, 0x48/4)); | |
343 | nv_wr32(dev, 0x3234, nv_ro32(dev, ramfc, 0x4c/4)); | |
344 | nv_wr32(dev, 0x3340, nv_ro32(dev, ramfc, 0x50/4)); | |
345 | nv_wr32(dev, 0x3344, nv_ro32(dev, ramfc, 0x54/4)); | |
346 | nv_wr32(dev, 0x3280, nv_ro32(dev, ramfc, 0x58/4)); | |
347 | nv_wr32(dev, 0x3254, nv_ro32(dev, ramfc, 0x5c/4)); | |
348 | nv_wr32(dev, 0x3260, nv_ro32(dev, ramfc, 0x60/4)); | |
349 | nv_wr32(dev, 0x3264, nv_ro32(dev, ramfc, 0x64/4)); | |
350 | nv_wr32(dev, 0x3268, nv_ro32(dev, ramfc, 0x68/4)); | |
351 | nv_wr32(dev, 0x326c, nv_ro32(dev, ramfc, 0x6c/4)); | |
352 | nv_wr32(dev, 0x32e4, nv_ro32(dev, ramfc, 0x70/4)); | |
353 | nv_wr32(dev, 0x3248, nv_ro32(dev, ramfc, 0x74/4)); | |
354 | nv_wr32(dev, 0x2088, nv_ro32(dev, ramfc, 0x78/4)); | |
355 | nv_wr32(dev, 0x2058, nv_ro32(dev, ramfc, 0x7c/4)); | |
356 | nv_wr32(dev, 0x2210, nv_ro32(dev, ramfc, 0x80/4)); | |
357 | ||
358 | cnt = nv_ro32(dev, ramfc, 0x84/4); | |
359 | for (ptr = 0; ptr < cnt; ptr++) { | |
360 | nv_wr32(dev, NV40_PFIFO_CACHE1_METHOD(ptr), | |
361 | nv_ro32(dev, cache, (ptr * 2) + 0)); | |
362 | nv_wr32(dev, NV40_PFIFO_CACHE1_DATA(ptr), | |
363 | nv_ro32(dev, cache, (ptr * 2) + 1)); | |
364 | } | |
7fb8ec8e BS |
365 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, cnt << 2); |
366 | nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); | |
6ee73861 BS |
367 | |
368 | /* guessing that all the 0x34xx regs aren't on NV50 */ | |
ac94a343 | 369 | if (dev_priv->chipset != 0x50) { |
6ee73861 BS |
370 | nv_wr32(dev, 0x340c, nv_ro32(dev, ramfc, 0x88/4)); |
371 | nv_wr32(dev, 0x3400, nv_ro32(dev, ramfc, 0x8c/4)); | |
372 | nv_wr32(dev, 0x3404, nv_ro32(dev, ramfc, 0x90/4)); | |
373 | nv_wr32(dev, 0x3408, nv_ro32(dev, ramfc, 0x94/4)); | |
374 | nv_wr32(dev, 0x3410, nv_ro32(dev, ramfc, 0x98/4)); | |
375 | } | |
376 | ||
6ee73861 BS |
377 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, chan->id | (1<<16)); |
378 | return 0; | |
379 | } | |
380 | ||
381 | int | |
382 | nv50_fifo_unload_context(struct drm_device *dev) | |
383 | { | |
384 | struct drm_nouveau_private *dev_priv = dev->dev_private; | |
385 | struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; | |
386 | struct nouveau_gpuobj *ramfc, *cache; | |
387 | struct nouveau_channel *chan = NULL; | |
388 | int chid, get, put, ptr; | |
389 | ||
390 | NV_DEBUG(dev, "\n"); | |
391 | ||
392 | chid = pfifo->channel_id(dev); | |
3c8868d3 | 393 | if (chid < 1 || chid >= dev_priv->engine.fifo.channels - 1) |
6ee73861 BS |
394 | return 0; |
395 | ||
396 | chan = dev_priv->fifos[chid]; | |
397 | if (!chan) { | |
398 | NV_ERROR(dev, "Inactive channel on PFIFO: %d\n", chid); | |
399 | return -EINVAL; | |
400 | } | |
401 | NV_DEBUG(dev, "ch%d\n", chan->id); | |
402 | ramfc = chan->ramfc->gpuobj; | |
403 | cache = chan->cache->gpuobj; | |
404 | ||
6ee73861 BS |
405 | nv_wo32(dev, ramfc, 0x00/4, nv_rd32(dev, 0x3330)); |
406 | nv_wo32(dev, ramfc, 0x04/4, nv_rd32(dev, 0x3334)); | |
407 | nv_wo32(dev, ramfc, 0x08/4, nv_rd32(dev, 0x3240)); | |
408 | nv_wo32(dev, ramfc, 0x0c/4, nv_rd32(dev, 0x3320)); | |
409 | nv_wo32(dev, ramfc, 0x10/4, nv_rd32(dev, 0x3244)); | |
410 | nv_wo32(dev, ramfc, 0x14/4, nv_rd32(dev, 0x3328)); | |
411 | nv_wo32(dev, ramfc, 0x18/4, nv_rd32(dev, 0x3368)); | |
412 | nv_wo32(dev, ramfc, 0x1c/4, nv_rd32(dev, 0x336c)); | |
413 | nv_wo32(dev, ramfc, 0x20/4, nv_rd32(dev, 0x3370)); | |
414 | nv_wo32(dev, ramfc, 0x24/4, nv_rd32(dev, 0x3374)); | |
415 | nv_wo32(dev, ramfc, 0x28/4, nv_rd32(dev, 0x3378)); | |
416 | nv_wo32(dev, ramfc, 0x2c/4, nv_rd32(dev, 0x337c)); | |
417 | nv_wo32(dev, ramfc, 0x30/4, nv_rd32(dev, 0x3228)); | |
418 | nv_wo32(dev, ramfc, 0x34/4, nv_rd32(dev, 0x3364)); | |
419 | nv_wo32(dev, ramfc, 0x38/4, nv_rd32(dev, 0x32a0)); | |
420 | nv_wo32(dev, ramfc, 0x3c/4, nv_rd32(dev, 0x3224)); | |
421 | nv_wo32(dev, ramfc, 0x40/4, nv_rd32(dev, 0x324c)); | |
422 | nv_wo32(dev, ramfc, 0x44/4, nv_rd32(dev, 0x2044)); | |
423 | nv_wo32(dev, ramfc, 0x48/4, nv_rd32(dev, 0x322c)); | |
424 | nv_wo32(dev, ramfc, 0x4c/4, nv_rd32(dev, 0x3234)); | |
425 | nv_wo32(dev, ramfc, 0x50/4, nv_rd32(dev, 0x3340)); | |
426 | nv_wo32(dev, ramfc, 0x54/4, nv_rd32(dev, 0x3344)); | |
427 | nv_wo32(dev, ramfc, 0x58/4, nv_rd32(dev, 0x3280)); | |
428 | nv_wo32(dev, ramfc, 0x5c/4, nv_rd32(dev, 0x3254)); | |
429 | nv_wo32(dev, ramfc, 0x60/4, nv_rd32(dev, 0x3260)); | |
430 | nv_wo32(dev, ramfc, 0x64/4, nv_rd32(dev, 0x3264)); | |
431 | nv_wo32(dev, ramfc, 0x68/4, nv_rd32(dev, 0x3268)); | |
432 | nv_wo32(dev, ramfc, 0x6c/4, nv_rd32(dev, 0x326c)); | |
433 | nv_wo32(dev, ramfc, 0x70/4, nv_rd32(dev, 0x32e4)); | |
434 | nv_wo32(dev, ramfc, 0x74/4, nv_rd32(dev, 0x3248)); | |
435 | nv_wo32(dev, ramfc, 0x78/4, nv_rd32(dev, 0x2088)); | |
436 | nv_wo32(dev, ramfc, 0x7c/4, nv_rd32(dev, 0x2058)); | |
437 | nv_wo32(dev, ramfc, 0x80/4, nv_rd32(dev, 0x2210)); | |
438 | ||
439 | put = (nv_rd32(dev, NV03_PFIFO_CACHE1_PUT) & 0x7ff) >> 2; | |
440 | get = (nv_rd32(dev, NV03_PFIFO_CACHE1_GET) & 0x7ff) >> 2; | |
441 | ptr = 0; | |
442 | while (put != get) { | |
443 | nv_wo32(dev, cache, ptr++, | |
444 | nv_rd32(dev, NV40_PFIFO_CACHE1_METHOD(get))); | |
445 | nv_wo32(dev, cache, ptr++, | |
446 | nv_rd32(dev, NV40_PFIFO_CACHE1_DATA(get))); | |
447 | get = (get + 1) & 0x1ff; | |
448 | } | |
449 | ||
450 | /* guessing that all the 0x34xx regs aren't on NV50 */ | |
ac94a343 | 451 | if (dev_priv->chipset != 0x50) { |
6ee73861 BS |
452 | nv_wo32(dev, ramfc, 0x84/4, ptr >> 1); |
453 | nv_wo32(dev, ramfc, 0x88/4, nv_rd32(dev, 0x340c)); | |
454 | nv_wo32(dev, ramfc, 0x8c/4, nv_rd32(dev, 0x3400)); | |
455 | nv_wo32(dev, ramfc, 0x90/4, nv_rd32(dev, 0x3404)); | |
456 | nv_wo32(dev, ramfc, 0x94/4, nv_rd32(dev, 0x3408)); | |
457 | nv_wo32(dev, ramfc, 0x98/4, nv_rd32(dev, 0x3410)); | |
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 |