Rev 883 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
883 | serge | 1 | #define RADEON_SCRATCH_REG0 0x15e0 |
2 | #define RADEON_SCRATCH_REG1 0x15e4 |
||
3 | #define RADEON_SCRATCH_REG2 0x15e8 |
||
4 | #define RADEON_SCRATCH_REG3 0x15ec |
||
5 | #define RADEON_SCRATCH_REG4 0x15f0 |
||
6 | #define RADEON_SCRATCH_REG5 0x15f4 |
||
7 | #define RADEON_SCRATCH_UMSK 0x0770 |
||
8 | #define RADEON_SCRATCH_ADDR 0x0774 |
||
9 | |||
10 | # define RS400_BUS_MASTER_DIS (1 << 14) |
||
11 | //# define RADEON_BUS_MASTER_DIS (1 << 6) |
||
12 | |||
13 | #define RADEON_ISYNC_CNTL 0x1724 |
||
14 | # define RADEON_ISYNC_ANY2D_IDLE3D (1 << 0) |
||
15 | # define RADEON_ISYNC_ANY3D_IDLE2D (1 << 1) |
||
16 | # define RADEON_ISYNC_TRIG2D_IDLE3D (1 << 2) |
||
17 | # define RADEON_ISYNC_TRIG3D_IDLE2D (1 << 3) |
||
18 | # define RADEON_ISYNC_WAIT_IDLEGUI (1 << 4) |
||
19 | # define RADEON_ISYNC_CPSCRATCH_IDLEGUI (1 << 5) |
||
20 | |||
21 | |||
22 | #define RADEON_IDLE_RETRY 16 /* Fall out of idle loops after this count */ |
||
23 | #define RADEON_TIMEOUT 2000000 /* Fall out of wait loops after this count */ |
||
24 | |||
25 | |||
26 | void RADEONPllErrataAfterIndex() |
||
27 | { |
||
28 | if (!(rhd.ChipErrata & CHIP_ERRATA_PLL_DUMMYREADS)) |
||
29 | return; |
||
30 | |||
31 | /* This workaround is necessary on rv200 and RS200 or PLL |
||
32 | * reads may return garbage (among others...) |
||
33 | */ |
||
34 | (void)INREG(RADEON_CLOCK_CNTL_DATA); |
||
35 | (void)INREG(RADEON_CRTC_GEN_CNTL); |
||
36 | } |
||
37 | |||
38 | |||
39 | void RADEONPllErrataAfterData() |
||
40 | { |
||
41 | |||
42 | /* This function is required to workaround a hardware bug in some (all?) |
||
43 | * revisions of the R300. This workaround should be called after every |
||
44 | * CLOCK_CNTL_INDEX register access. If not, register reads afterward |
||
45 | * may not be correct. |
||
46 | */ |
||
47 | if (rhd.ChipFamily <= CHIP_FAMILY_RV380) |
||
48 | { |
||
49 | u32_t save, tmp; |
||
50 | |||
51 | save = INREG(RADEON_CLOCK_CNTL_INDEX); |
||
52 | tmp = save & ~(0x3f | RADEON_PLL_WR_EN); |
||
53 | OUTREG(RADEON_CLOCK_CNTL_INDEX, tmp); |
||
54 | tmp = INREG(RADEON_CLOCK_CNTL_DATA); |
||
55 | OUTREG(RADEON_CLOCK_CNTL_INDEX, save); |
||
56 | } |
||
57 | } |
||
58 | |||
59 | |||
60 | /* Read PLL register */ |
||
61 | u32_t RADEONINPLL(int addr) |
||
62 | { |
||
63 | u32_t data; |
||
64 | |||
65 | OUTREG8(RADEON_CLOCK_CNTL_INDEX, addr & 0x3f); |
||
66 | RADEONPllErrataAfterIndex(); |
||
67 | data = INREG(RADEON_CLOCK_CNTL_DATA); |
||
68 | RADEONPllErrataAfterData(); |
||
69 | |||
70 | return data; |
||
71 | }; |
||
72 | |||
73 | /* Write PLL information */ |
||
74 | void RADEONOUTPLL(int addr, u32_t data) |
||
75 | { |
||
76 | OUTREG8(RADEON_CLOCK_CNTL_INDEX, (((addr) & 0x3f) | |
||
77 | RADEON_PLL_WR_EN)); |
||
78 | RADEONPllErrataAfterIndex(); |
||
79 | OUTREG(RADEON_CLOCK_CNTL_DATA, data); |
||
80 | RADEONPllErrataAfterData(); |
||
81 | } |
||
82 | |||
83 | void RADEONEngineFlush(RHDPtr info) |
||
84 | { |
||
85 | int i; |
||
86 | |||
87 | if (info->ChipFamily <= CHIP_FAMILY_RV280) |
||
88 | { |
||
89 | MASKREG(RADEON_RB3D_DSTCACHE_CTLSTAT,RADEON_RB3D_DC_FLUSH_ALL, |
||
90 | ~RADEON_RB3D_DC_FLUSH_ALL); |
||
91 | for (i = 0; i < RADEON_TIMEOUT; i++) { |
||
92 | if (!(INREG(RADEON_RB3D_DSTCACHE_CTLSTAT) & RADEON_RB3D_DC_BUSY)) |
||
93 | break; |
||
94 | } |
||
95 | if (i == RADEON_TIMEOUT) { |
||
96 | dbgprintf("DC flush timeout: %x\n", |
||
97 | (u32_t)INREG(RADEON_RB3D_DSTCACHE_CTLSTAT)); |
||
98 | } |
||
99 | } |
||
100 | else |
||
101 | { |
||
102 | // MASKREG(R300_DSTCACHE_CTLSTAT,R300_RB2D_DC_FLUSH_ALL, |
||
103 | // ~R300_RB2D_DC_FLUSH_ALL); |
||
104 | // for (i = 0; i < RADEON_TIMEOUT; i++) { |
||
105 | // if (!(INREG(R300_DSTCACHE_CTLSTAT) & R300_RB2D_DC_BUSY)) |
||
106 | // break; |
||
107 | // } |
||
108 | // if (i == RADEON_TIMEOUT) { |
||
109 | // dbgprintf("DC flush timeout: %x\n", |
||
110 | // (u32_t)INREG(R300_DSTCACHE_CTLSTAT)); |
||
111 | // } |
||
112 | } |
||
113 | } |
||
114 | |||
115 | static Bool R5xxFIFOWaitLocal(u32_t required) //R100-R500 |
||
116 | { |
||
117 | int i; |
||
118 | |||
119 | for (i = 0; i < RADEON_TIMEOUT; i++) |
||
120 | if (required <= (INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK)) |
||
121 | return TRUE; |
||
122 | |||
123 | dbgprintf("%s: Timeout 0x%08X.\n", __func__, (u32_t) INREG(RADEON_RBBM_STATUS)); |
||
124 | return FALSE; |
||
125 | } |
||
126 | |||
127 | static int radeon_do_wait_for_idle() |
||
128 | { |
||
129 | int i, ret; |
||
130 | |||
131 | ret = R5xxFIFOWaitLocal(64); |
||
132 | if (ret) |
||
133 | return ret; |
||
134 | |||
135 | for (i = 0; i < RADEON_TIMEOUT; i++) |
||
136 | { |
||
137 | if (!(INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE)) { |
||
138 | RADEONEngineFlush(&rhd); |
||
139 | return 0; |
||
140 | } |
||
141 | usleep(1); |
||
142 | } |
||
143 | dbgprintf("wait idle failed status : 0x%08X 0x%08X\n", |
||
144 | INREG(RADEON_RBBM_STATUS), |
||
145 | INREG(R300_VAP_CNTL_STATUS)); |
||
146 | |||
147 | return 1; |
||
148 | } |
||
149 | |||
150 | |||
151 | static void init_pipes(RHDPtr info) |
||
152 | { |
||
153 | u32_t gb_tile_config = 0; |
||
154 | |||
155 | if ( (info->ChipFamily == CHIP_FAMILY_RV410) || |
||
156 | (info->ChipFamily == CHIP_FAMILY_R420) || |
||
157 | (info->ChipFamily == CHIP_FAMILY_RS600) || |
||
158 | (info->ChipFamily == CHIP_FAMILY_RS690) || |
||
159 | (info->ChipFamily == CHIP_FAMILY_RS740) || |
||
160 | (info->ChipFamily == CHIP_FAMILY_RS400) || |
||
161 | (info->ChipFamily == CHIP_FAMILY_RS480) || IS_R500_3D) |
||
162 | { |
||
163 | u32_t gb_pipe_sel = INREG(R400_GB_PIPE_SELECT); |
||
164 | |||
165 | info->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1; |
||
166 | if (IS_R500_3D) |
||
167 | OUTPLL(R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4)); |
||
168 | } |
||
169 | else |
||
170 | { |
||
171 | if ((info->ChipFamily == CHIP_FAMILY_R300) || |
||
172 | (info->ChipFamily == CHIP_FAMILY_R350)) |
||
173 | { |
||
174 | /* R3xx chips */ |
||
175 | info->num_gb_pipes = 2; |
||
176 | } |
||
177 | else { |
||
178 | /* RV3xx chips */ |
||
179 | info->num_gb_pipes = 1; |
||
180 | } |
||
181 | } |
||
182 | |||
183 | if (IS_R300_3D || IS_R500_3D) |
||
184 | { |
||
185 | |||
186 | dbgprintf("num quad-pipes is %d\n", info->num_gb_pipes); |
||
187 | |||
188 | switch(info->num_gb_pipes) { |
||
189 | case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break; |
||
190 | case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break; |
||
191 | case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break; |
||
192 | default: |
||
193 | case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break; |
||
194 | } |
||
195 | |||
196 | OUTREG(R300_GB_TILE_CONFIG, gb_tile_config); |
||
197 | OUTREG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); |
||
198 | OUTREG(R300_DST_PIPE_CONFIG, INREG(R300_DST_PIPE_CONFIG) | R300_PIPE_AUTO_CONFIG); |
||
199 | OUTREG(R300_RB2D_DSTCACHE_MODE, (INREG(R300_RB2D_DSTCACHE_MODE) | |
||
200 | R300_DC_AUTOFLUSH_ENABLE | |
||
201 | R300_DC_DC_DISABLE_IGNORE_PE)); |
||
202 | } |
||
203 | else |
||
204 | OUTREG(RADEON_RB3D_CNTL, 0); |
||
205 | }; |
||
206 | |||
207 | /* ================================================================ |
||
208 | * CP control, initialization |
||
209 | */ |
||
210 | |||
211 | /* Load the microcode for the CP */ |
||
212 | |||
213 | #include "radeon_microcode.h" |
||
214 | |||
215 | static void load_microcode(RHDPtr info) |
||
216 | { |
||
217 | int i; |
||
218 | const u32_t (*microcode)[2]; |
||
219 | |||
220 | OUTREG(RADEON_CP_ME_RAM_ADDR, 0); |
||
221 | |||
222 | if ( (info->ChipFamily == CHIP_FAMILY_LEGACY ) || |
||
223 | (info->ChipFamily == CHIP_FAMILY_RADEON ) || |
||
224 | (info->ChipFamily == CHIP_FAMILY_RV100 ) || |
||
225 | (info->ChipFamily == CHIP_FAMILY_RV200 ) || |
||
226 | (info->ChipFamily == CHIP_FAMILY_RS100 ) || |
||
227 | (info->ChipFamily == CHIP_FAMILY_RS200 )) |
||
228 | { |
||
229 | microcode = R100_cp_microcode; |
||
230 | dbgprintf("Loading R100 Microcode\n"); |
||
231 | } |
||
232 | else if ((info->ChipFamily == CHIP_FAMILY_R200 ) || |
||
233 | (info->ChipFamily == CHIP_FAMILY_RV250) || |
||
234 | (info->ChipFamily == CHIP_FAMILY_RV280) || |
||
235 | (info->ChipFamily == CHIP_FAMILY_RS300)) |
||
236 | { |
||
237 | microcode = R200_cp_microcode; |
||
238 | dbgprintf("Loading R200 Microcode\n"); |
||
239 | } |
||
240 | else if ((info->ChipFamily == CHIP_FAMILY_R300) || |
||
241 | (info->ChipFamily == CHIP_FAMILY_R350) || |
||
242 | (info->ChipFamily == CHIP_FAMILY_RV350) || |
||
243 | (info->ChipFamily == CHIP_FAMILY_RV380) || |
||
244 | (info->ChipFamily == CHIP_FAMILY_RS400) || |
||
245 | (info->ChipFamily == CHIP_FAMILY_RS480)) |
||
246 | { |
||
247 | dbgprintf("Loading R300 Microcode\n"); |
||
248 | microcode = R300_cp_microcode; |
||
249 | } |
||
250 | else if ((info->ChipFamily == CHIP_FAMILY_R420) || |
||
251 | (info->ChipFamily == CHIP_FAMILY_RV410)) |
||
252 | { |
||
253 | dbgprintf("Loading R400 Microcode\n"); |
||
254 | microcode = R420_cp_microcode; |
||
255 | |||
256 | } |
||
257 | else if ((info->ChipFamily == CHIP_FAMILY_RS600) || |
||
258 | (info->ChipFamily == CHIP_FAMILY_RS690) || |
||
259 | (info->ChipFamily == CHIP_FAMILY_RS740)) |
||
260 | { |
||
261 | dbgprintf("Loading RS690/RS740 Microcode\n"); |
||
262 | microcode = RS690_cp_microcode; |
||
263 | } |
||
264 | else if ((info->ChipFamily == CHIP_FAMILY_RV515) || |
||
265 | (info->ChipFamily == CHIP_FAMILY_R520) || |
||
266 | (info->ChipFamily == CHIP_FAMILY_RV530) || |
||
267 | (info->ChipFamily == CHIP_FAMILY_R580) || |
||
268 | (info->ChipFamily == CHIP_FAMILY_RV560) || |
||
269 | (info->ChipFamily == CHIP_FAMILY_RV570)) |
||
270 | { |
||
271 | dbgprintf("Loading R500 Microcode\n"); |
||
272 | microcode = R520_cp_microcode; |
||
273 | } |
||
274 | |||
275 | for (i = 0; i < 256; i++) { |
||
276 | OUTREG(RADEON_CP_ME_RAM_DATAH, microcode[i][1]); |
||
277 | OUTREG(RADEON_CP_ME_RAM_DATAL, microcode[i][0]); |
||
278 | } |
||
279 | } |
||
280 | |||
281 | |||
282 | void init_ring_buffer(RHDPtr info) |
||
283 | { |
||
284 | u32_t ring_base; |
||
285 | u32_t tmp; |
||
286 | |||
287 | info->ringBase = CreateRingBuffer( 64*1024, PG_SW); |
||
288 | |||
289 | dbgprintf("create cp ring buffer %x\n", rhd.ringBase); |
||
290 | ring_base = GetPgAddr(rhd.ringBase); |
||
291 | dbgprintf("ring base %x\n", ring_base); |
||
292 | |||
293 | OUTREG(RADEON_CP_RB_BASE, ring_base); |
||
294 | |||
295 | info->ring_avail = 64*1024/4 ; |
||
296 | |||
297 | /* Set the write pointer delay */ |
||
298 | OUTREG(RADEON_CP_RB_WPTR_DELAY, 0); |
||
299 | |||
300 | /* Initialize the ring buffer's read and write pointers */ |
||
301 | rhd.ring_rp = rhd.ring_wp = INREG(RADEON_CP_RB_RPTR); |
||
302 | rhd.host_rp = rhd.ring_rp; |
||
303 | |||
304 | OUTREG(RADEON_CP_RB_WPTR,rhd.ring_rp); |
||
305 | |||
885 | serge | 306 | tmp = (((u32_t)&rhd.host_rp) & 4095) + GetPgAddr((void*)&rhd.host_rp); |
883 | serge | 307 | |
308 | OUTREG(RADEON_CP_RB_RPTR_ADDR, tmp); // ring buffer read pointer |
||
309 | |||
310 | /* Set ring buffer size */ |
||
311 | OUTREG(RADEON_CP_RB_CNTL, (1<<27)|(0<<18)|(10<<8)|13); |
||
312 | |||
313 | /* Initialize the scratch register pointer. This will cause |
||
314 | * the scratch register values to be written out to memory |
||
315 | * whenever they are updated. |
||
316 | * |
||
317 | * We simply put this behind the ring read pointer, this works |
||
318 | * with PCI GART as well as (whatever kind of) AGP GART |
||
319 | */ |
||
320 | |||
885 | serge | 321 | tmp = (((u32_t)&rhd.scratch0) & 4095) + GetPgAddr((void*)&rhd.scratch0); |
883 | serge | 322 | OUTREG(RADEON_SCRATCH_ADDR, tmp); |
323 | |||
324 | OUTREG(RADEON_SCRATCH_UMSK, 0x0); |
||
325 | //OUTREG(0x778, 1); |
||
326 | |||
327 | /* Turn on bus mastering */ |
||
328 | if ( (info->ChipFamily == CHIP_FAMILY_RS400) || |
||
329 | (info->ChipFamily == CHIP_FAMILY_RS690) || |
||
330 | (info->ChipFamily == CHIP_FAMILY_RS740) ) |
||
331 | { |
||
332 | /* rs400, rs690/rs740 */ |
||
333 | tmp = INREG(RADEON_BUS_CNTL) & ~RS400_BUS_MASTER_DIS; |
||
334 | OUTREG(RADEON_BUS_CNTL, tmp); |
||
335 | } |
||
336 | else if (!((info->ChipFamily == CHIP_FAMILY_RV380) || |
||
337 | (info->ChipFamily >= CHIP_FAMILY_R420))) |
||
338 | { |
||
339 | /* r1xx, r2xx, r300, r(v)350, r420/r481, rs480 */ |
||
340 | tmp = INREG(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; |
||
341 | OUTREG(RADEON_BUS_CNTL, tmp); |
||
342 | } /* PCIE cards appears to not need this */ |
||
343 | |||
344 | tmp = INREG(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; |
||
345 | OUTREG(RADEON_BUS_CNTL, tmp); |
||
346 | |||
347 | radeon_do_wait_for_idle(); |
||
348 | |||
349 | /* Sync everything up */ |
||
350 | OUTREG(RADEON_ISYNC_CNTL, |
||
351 | (RADEON_ISYNC_ANY2D_IDLE3D | |
||
352 | RADEON_ISYNC_ANY3D_IDLE2D | |
||
353 | RADEON_ISYNC_WAIT_IDLEGUI | |
||
354 | RADEON_ISYNC_CPSCRATCH_IDLEGUI)); |
||
355 | } |
||
356 | |||
357 | |||
358 | void radeon_engine_reset(RHDPtr info) |
||
359 | { |
||
360 | u32_t clock_cntl_index; |
||
361 | u32_t mclk_cntl; |
||
362 | u32_t rbbm_soft_reset; |
||
363 | u32_t host_path_cntl; |
||
364 | |||
365 | if (info->ChipFamily <= CHIP_FAMILY_RV410) |
||
366 | { |
||
367 | /* may need something similar for newer chips */ |
||
368 | clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX); |
||
369 | mclk_cntl = INPLL( RADEON_MCLK_CNTL); |
||
370 | |||
371 | OUTPLL(RADEON_MCLK_CNTL, (mclk_cntl | |
||
372 | RADEON_FORCEON_MCLKA | |
||
373 | RADEON_FORCEON_MCLKB | |
||
374 | RADEON_FORCEON_YCLKA | |
||
375 | RADEON_FORCEON_YCLKB | |
||
376 | RADEON_FORCEON_MC | |
||
377 | RADEON_FORCEON_AIC)); |
||
378 | } |
||
379 | |||
380 | rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET); |
||
381 | |||
382 | OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset | |
||
383 | RADEON_SOFT_RESET_CP | |
||
384 | RADEON_SOFT_RESET_HI | |
||
385 | RADEON_SOFT_RESET_SE | |
||
386 | RADEON_SOFT_RESET_RE | |
||
387 | RADEON_SOFT_RESET_PP | |
||
388 | RADEON_SOFT_RESET_E2 | |
||
389 | RADEON_SOFT_RESET_RB)); |
||
390 | INREG(RADEON_RBBM_SOFT_RESET); |
||
391 | OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset & |
||
392 | ~(RADEON_SOFT_RESET_CP | |
||
393 | RADEON_SOFT_RESET_HI | |
||
394 | RADEON_SOFT_RESET_SE | |
||
395 | RADEON_SOFT_RESET_RE | |
||
396 | RADEON_SOFT_RESET_PP | |
||
397 | RADEON_SOFT_RESET_E2 | |
||
398 | RADEON_SOFT_RESET_RB))); |
||
399 | INREG(RADEON_RBBM_SOFT_RESET); |
||
400 | |||
401 | if (info->ChipFamily <= CHIP_FAMILY_RV410) { |
||
402 | OUTPLL(RADEON_MCLK_CNTL, mclk_cntl); |
||
403 | OUTREG(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index); |
||
404 | OUTREG(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset); |
||
405 | } |
||
406 | }; |
||
407 | |||
408 | #define RADEON_WAIT_UNTIL_IDLE() do { \ |
||
409 | OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 1 ) ); \ |
||
410 | OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \ |
||
411 | RADEON_WAIT_3D_IDLECLEAN | \ |
||
412 | RADEON_WAIT_HOST_IDLECLEAN) ); \ |
||
413 | } while (0) |
||
414 | |||
415 | #define R300_ZB_ZCACHE_CTLSTAT 0x4f18 |
||
416 | # define RADEON_RB3D_ZC_FLUSH (1 << 0) |
||
417 | # define RADEON_RB3D_ZC_FREE (1 << 2) |
||
418 | # define RADEON_RB3D_ZC_FLUSH_ALL 0x5 |
||
419 | # define RADEON_RB3D_ZC_BUSY (1 << 31) |
||
420 | # define R300_ZC_FLUSH (1 << 0) |
||
421 | # define R300_ZC_FREE (1 << 1) |
||
422 | # define R300_ZC_BUSY (1 << 31) |
||
423 | # define RADEON_RB3D_DC_FLUSH (3 << 0) |
||
424 | # define RADEON_RB3D_DC_FREE (3 << 2) |
||
425 | # define RADEON_RB3D_DC_FLUSH_ALL 0xf |
||
426 | # define RADEON_RB3D_DC_BUSY (1 << 31) |
||
427 | # define R300_RB3D_DC_FLUSH (2 << 0) |
||
428 | # define R300_RB3D_DC_FREE (2 << 2) |
||
429 | # |
||
430 | #define RADEON_PURGE_CACHE() do { \ |
||
431 | if ( rhd.ChipFamily <= CHIP_FAMILY_RV280) { \ |
||
432 | OUT_RING(CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 1)); \ |
||
433 | OUT_RING(RADEON_RB3D_DC_FLUSH | RADEON_RB3D_DC_FREE); \ |
||
434 | } else { \ |
||
435 | OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 1)); \ |
||
436 | OUT_RING(R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE ); \ |
||
437 | } \ |
||
438 | } while (0) |
||
439 | |||
440 | #define RADEON_FLUSH_ZCACHE() do { \ |
||
441 | if ( rhd.ChipFamily <= CHIP_FAMILY_RV280) { \ |
||
442 | OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 1 ) ); \ |
||
443 | OUT_RING( RADEON_RB3D_ZC_FLUSH ); \ |
||
444 | } else { \ |
||
445 | OUT_RING( CP_PACKET0( R300_ZB_ZCACHE_CTLSTAT, 1 ) ); \ |
||
446 | OUT_RING( R300_ZC_FLUSH ); \ |
||
447 | } \ |
||
448 | } while (0) |
||
449 | #define RADEON_PURGE_ZCACHE() do { \ |
||
450 | if (rhd.ChipFamily <= CHIP_FAMILY_RV280) { \ |
||
451 | OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 1)); \ |
||
452 | OUT_RING(RADEON_RB3D_ZC_FLUSH | RADEON_RB3D_ZC_FREE); \ |
||
453 | } else { \ |
||
454 | OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 1)); \ |
||
455 | OUT_RING(R300_ZC_FLUSH | R300_ZC_FREE); \ |
||
456 | } \ |
||
457 | } while (0) |
||
458 | |||
459 | static int radeon_cp_start(RHDPtr info) |
||
460 | { |
||
461 | u32_t *ring, write; |
||
462 | u32_t ifl; |
||
463 | radeon_do_wait_for_idle(64); |
||
464 | |||
465 | OUTREG(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM); |
||
466 | |||
467 | ifl = safe_cli(); |
||
468 | |||
469 | BEGIN_RING(8); |
||
470 | /* isync can only be written through cp on r5xx write it here */ |
||
471 | OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 1)); |
||
472 | OUT_RING(RADEON_ISYNC_ANY2D_IDLE3D | |
||
473 | RADEON_ISYNC_ANY3D_IDLE2D | |
||
474 | RADEON_ISYNC_WAIT_IDLEGUI | |
||
475 | RADEON_ISYNC_CPSCRATCH_IDLEGUI); |
||
476 | RADEON_PURGE_CACHE(); |
||
477 | RADEON_PURGE_ZCACHE(); |
||
478 | RADEON_WAIT_UNTIL_IDLE(); |
||
479 | ADVANCE_RING(); |
||
480 | COMMIT_RING(); |
||
481 | |||
482 | safe_sti(ifl); |
||
483 | |||
484 | radeon_do_wait_for_idle(); |
||
485 | }; |
||
486 | |||
487 | |||
488 | Bool init_cp(RHDPtr info) |
||
489 | { |
||
490 | load_microcode(&rhd); |
||
491 | |||
492 | init_ring_buffer(&rhd); |
||
493 | |||
494 | radeon_engine_reset(&rhd); |
||
495 | |||
496 | /* setup the raster pipes */ |
||
497 | init_pipes(&rhd); |
||
498 | |||
499 | rhd.ring_rp = rhd.ring_wp = INREG(RADEON_CP_RB_RPTR); |
||
500 | OUTREG(RADEON_CP_RB_WPTR, rhd.ring_rp); |
||
501 | |||
502 | radeon_cp_start(&rhd); |
||
503 | |||
504 | };=>=>=>><>><>><>><>><>><>><>><>><>><>><>=>=>8)|13); |
||
505 | |||
506 |