Rev 885 | 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 */ |
||
1002 | serge | 23 | #define RADEON_TIMEOUT 4000000 /* Fall out of wait loops after this count */ |
883 | serge | 24 | |
25 | |||
26 | |||
27 | void RADEONEngineFlush(RHDPtr info) |
||
28 | { |
||
29 | int i; |
||
30 | |||
31 | if (info->ChipFamily <= CHIP_FAMILY_RV280) |
||
32 | { |
||
33 | MASKREG(RADEON_RB3D_DSTCACHE_CTLSTAT,RADEON_RB3D_DC_FLUSH_ALL, |
||
34 | ~RADEON_RB3D_DC_FLUSH_ALL); |
||
35 | for (i = 0; i < RADEON_TIMEOUT; i++) { |
||
36 | if (!(INREG(RADEON_RB3D_DSTCACHE_CTLSTAT) & RADEON_RB3D_DC_BUSY)) |
||
37 | break; |
||
38 | } |
||
39 | if (i == RADEON_TIMEOUT) { |
||
40 | dbgprintf("DC flush timeout: %x\n", |
||
41 | (u32_t)INREG(RADEON_RB3D_DSTCACHE_CTLSTAT)); |
||
42 | } |
||
43 | } |
||
44 | else |
||
45 | { |
||
46 | // MASKREG(R300_DSTCACHE_CTLSTAT,R300_RB2D_DC_FLUSH_ALL, |
||
47 | // ~R300_RB2D_DC_FLUSH_ALL); |
||
48 | // for (i = 0; i < RADEON_TIMEOUT; i++) { |
||
49 | // if (!(INREG(R300_DSTCACHE_CTLSTAT) & R300_RB2D_DC_BUSY)) |
||
50 | // break; |
||
51 | // } |
||
52 | // if (i == RADEON_TIMEOUT) { |
||
53 | // dbgprintf("DC flush timeout: %x\n", |
||
54 | // (u32_t)INREG(R300_DSTCACHE_CTLSTAT)); |
||
55 | // } |
||
56 | } |
||
57 | } |
||
58 | |||
59 | static Bool R5xxFIFOWaitLocal(u32_t required) //R100-R500 |
||
60 | { |
||
61 | int i; |
||
62 | |||
63 | for (i = 0; i < RADEON_TIMEOUT; i++) |
||
64 | if (required <= (INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK)) |
||
65 | return TRUE; |
||
66 | |||
67 | dbgprintf("%s: Timeout 0x%08X.\n", __func__, (u32_t) INREG(RADEON_RBBM_STATUS)); |
||
68 | return FALSE; |
||
69 | } |
||
70 | |||
71 | static int radeon_do_wait_for_idle() |
||
72 | { |
||
73 | int i, ret; |
||
74 | |||
75 | ret = R5xxFIFOWaitLocal(64); |
||
76 | if (ret) |
||
77 | return ret; |
||
78 | |||
79 | for (i = 0; i < RADEON_TIMEOUT; i++) |
||
80 | { |
||
81 | if (!(INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE)) { |
||
82 | RADEONEngineFlush(&rhd); |
||
83 | return 0; |
||
84 | } |
||
85 | usleep(1); |
||
86 | } |
||
87 | dbgprintf("wait idle failed status : 0x%08X 0x%08X\n", |
||
88 | INREG(RADEON_RBBM_STATUS), |
||
89 | INREG(R300_VAP_CNTL_STATUS)); |
||
90 | |||
91 | return 1; |
||
92 | } |
||
93 | |||
94 | |||
95 | |||
96 | /* ================================================================ |
||
97 | * CP control, initialization |
||
98 | */ |
||
99 | |||
100 | /* Load the microcode for the CP */ |
||
101 | |||
102 | #include "radeon_microcode.h" |
||
103 | |||
104 | static void load_microcode(RHDPtr info) |
||
105 | { |
||
106 | int i; |
||
107 | const u32_t (*microcode)[2]; |
||
108 | |||
109 | OUTREG(RADEON_CP_ME_RAM_ADDR, 0); |
||
110 | |||
111 | if ( (info->ChipFamily == CHIP_FAMILY_LEGACY ) || |
||
112 | (info->ChipFamily == CHIP_FAMILY_RADEON ) || |
||
113 | (info->ChipFamily == CHIP_FAMILY_RV100 ) || |
||
114 | (info->ChipFamily == CHIP_FAMILY_RV200 ) || |
||
115 | (info->ChipFamily == CHIP_FAMILY_RS100 ) || |
||
116 | (info->ChipFamily == CHIP_FAMILY_RS200 )) |
||
117 | { |
||
118 | microcode = R100_cp_microcode; |
||
119 | dbgprintf("Loading R100 Microcode\n"); |
||
120 | } |
||
121 | else if ((info->ChipFamily == CHIP_FAMILY_R200 ) || |
||
122 | (info->ChipFamily == CHIP_FAMILY_RV250) || |
||
123 | (info->ChipFamily == CHIP_FAMILY_RV280) || |
||
124 | (info->ChipFamily == CHIP_FAMILY_RS300)) |
||
125 | { |
||
126 | microcode = R200_cp_microcode; |
||
127 | dbgprintf("Loading R200 Microcode\n"); |
||
128 | } |
||
129 | else if ((info->ChipFamily == CHIP_FAMILY_R300) || |
||
130 | (info->ChipFamily == CHIP_FAMILY_R350) || |
||
131 | (info->ChipFamily == CHIP_FAMILY_RV350) || |
||
132 | (info->ChipFamily == CHIP_FAMILY_RV380) || |
||
133 | (info->ChipFamily == CHIP_FAMILY_RS400) || |
||
134 | (info->ChipFamily == CHIP_FAMILY_RS480)) |
||
135 | { |
||
136 | dbgprintf("Loading R300 Microcode\n"); |
||
137 | microcode = R300_cp_microcode; |
||
138 | } |
||
139 | else if ((info->ChipFamily == CHIP_FAMILY_R420) || |
||
140 | (info->ChipFamily == CHIP_FAMILY_RV410)) |
||
141 | { |
||
142 | dbgprintf("Loading R400 Microcode\n"); |
||
143 | microcode = R420_cp_microcode; |
||
144 | |||
145 | } |
||
146 | else if ((info->ChipFamily == CHIP_FAMILY_RS600) || |
||
147 | (info->ChipFamily == CHIP_FAMILY_RS690) || |
||
148 | (info->ChipFamily == CHIP_FAMILY_RS740)) |
||
149 | { |
||
150 | dbgprintf("Loading RS690/RS740 Microcode\n"); |
||
151 | microcode = RS690_cp_microcode; |
||
152 | } |
||
153 | else if ((info->ChipFamily == CHIP_FAMILY_RV515) || |
||
154 | (info->ChipFamily == CHIP_FAMILY_R520) || |
||
155 | (info->ChipFamily == CHIP_FAMILY_RV530) || |
||
156 | (info->ChipFamily == CHIP_FAMILY_R580) || |
||
157 | (info->ChipFamily == CHIP_FAMILY_RV560) || |
||
158 | (info->ChipFamily == CHIP_FAMILY_RV570)) |
||
159 | { |
||
160 | dbgprintf("Loading R500 Microcode\n"); |
||
161 | microcode = R520_cp_microcode; |
||
162 | } |
||
163 | |||
164 | for (i = 0; i < 256; i++) { |
||
165 | OUTREG(RADEON_CP_ME_RAM_DATAH, microcode[i][1]); |
||
166 | OUTREG(RADEON_CP_ME_RAM_DATAL, microcode[i][0]); |
||
167 | } |
||
168 | } |
||
169 | |||
170 | |||
171 | void init_ring_buffer(RHDPtr info) |
||
172 | { |
||
173 | u32_t ring_base; |
||
174 | u32_t tmp; |
||
175 | |||
176 | info->ringBase = CreateRingBuffer( 64*1024, PG_SW); |
||
177 | |||
178 | dbgprintf("create cp ring buffer %x\n", rhd.ringBase); |
||
179 | ring_base = GetPgAddr(rhd.ringBase); |
||
180 | dbgprintf("ring base %x\n", ring_base); |
||
181 | |||
182 | OUTREG(RADEON_CP_RB_BASE, ring_base); |
||
183 | |||
184 | info->ring_avail = 64*1024/4 ; |
||
185 | |||
186 | /* Set the write pointer delay */ |
||
187 | OUTREG(RADEON_CP_RB_WPTR_DELAY, 0); |
||
188 | |||
189 | /* Initialize the ring buffer's read and write pointers */ |
||
190 | rhd.ring_rp = rhd.ring_wp = INREG(RADEON_CP_RB_RPTR); |
||
191 | rhd.host_rp = rhd.ring_rp; |
||
192 | |||
193 | OUTREG(RADEON_CP_RB_WPTR,rhd.ring_rp); |
||
194 | |||
885 | serge | 195 | tmp = (((u32_t)&rhd.host_rp) & 4095) + GetPgAddr((void*)&rhd.host_rp); |
883 | serge | 196 | |
197 | OUTREG(RADEON_CP_RB_RPTR_ADDR, tmp); // ring buffer read pointer |
||
198 | |||
199 | /* Set ring buffer size */ |
||
200 | OUTREG(RADEON_CP_RB_CNTL, (1<<27)|(0<<18)|(10<<8)|13); |
||
201 | |||
202 | /* Initialize the scratch register pointer. This will cause |
||
203 | * the scratch register values to be written out to memory |
||
204 | * whenever they are updated. |
||
205 | * |
||
206 | * We simply put this behind the ring read pointer, this works |
||
207 | * with PCI GART as well as (whatever kind of) AGP GART |
||
208 | */ |
||
209 | |||
885 | serge | 210 | tmp = (((u32_t)&rhd.scratch0) & 4095) + GetPgAddr((void*)&rhd.scratch0); |
883 | serge | 211 | OUTREG(RADEON_SCRATCH_ADDR, tmp); |
212 | |||
213 | OUTREG(RADEON_SCRATCH_UMSK, 0x0); |
||
214 | //OUTREG(0x778, 1); |
||
215 | |||
216 | /* Turn on bus mastering */ |
||
217 | if ( (info->ChipFamily == CHIP_FAMILY_RS400) || |
||
218 | (info->ChipFamily == CHIP_FAMILY_RS690) || |
||
219 | (info->ChipFamily == CHIP_FAMILY_RS740) ) |
||
220 | { |
||
221 | /* rs400, rs690/rs740 */ |
||
222 | tmp = INREG(RADEON_BUS_CNTL) & ~RS400_BUS_MASTER_DIS; |
||
223 | OUTREG(RADEON_BUS_CNTL, tmp); |
||
224 | } |
||
225 | else if (!((info->ChipFamily == CHIP_FAMILY_RV380) || |
||
226 | (info->ChipFamily >= CHIP_FAMILY_R420))) |
||
227 | { |
||
228 | /* r1xx, r2xx, r300, r(v)350, r420/r481, rs480 */ |
||
229 | tmp = INREG(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; |
||
230 | OUTREG(RADEON_BUS_CNTL, tmp); |
||
231 | } /* PCIE cards appears to not need this */ |
||
232 | |||
233 | tmp = INREG(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; |
||
234 | OUTREG(RADEON_BUS_CNTL, tmp); |
||
235 | |||
236 | radeon_do_wait_for_idle(); |
||
237 | |||
238 | /* Sync everything up */ |
||
239 | OUTREG(RADEON_ISYNC_CNTL, |
||
240 | (RADEON_ISYNC_ANY2D_IDLE3D | |
||
241 | RADEON_ISYNC_ANY3D_IDLE2D | |
||
242 | RADEON_ISYNC_WAIT_IDLEGUI | |
||
243 | RADEON_ISYNC_CPSCRATCH_IDLEGUI)); |
||
244 | } |
||
245 | |||
246 | |||
247 | void radeon_engine_reset(RHDPtr info) |
||
248 | { |
||
1002 | serge | 249 | u32_t clock_cntl_index; |
250 | u32_t mclk_cntl; |
||
251 | u32_t rbbm_soft_reset; |
||
252 | u32_t host_path_cntl; |
||
883 | serge | 253 | |
254 | if (info->ChipFamily <= CHIP_FAMILY_RV410) |
||
255 | { |
||
256 | /* may need something similar for newer chips */ |
||
257 | clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX); |
||
258 | mclk_cntl = INPLL( RADEON_MCLK_CNTL); |
||
259 | |||
260 | OUTPLL(RADEON_MCLK_CNTL, (mclk_cntl | |
||
261 | RADEON_FORCEON_MCLKA | |
||
262 | RADEON_FORCEON_MCLKB | |
||
263 | RADEON_FORCEON_YCLKA | |
||
264 | RADEON_FORCEON_YCLKB | |
||
265 | RADEON_FORCEON_MC | |
||
266 | RADEON_FORCEON_AIC)); |
||
267 | } |
||
268 | |||
269 | rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET); |
||
270 | |||
271 | OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset | |
||
272 | RADEON_SOFT_RESET_CP | |
||
273 | RADEON_SOFT_RESET_HI | |
||
274 | RADEON_SOFT_RESET_SE | |
||
275 | RADEON_SOFT_RESET_RE | |
||
276 | RADEON_SOFT_RESET_PP | |
||
277 | RADEON_SOFT_RESET_E2 | |
||
278 | RADEON_SOFT_RESET_RB)); |
||
279 | INREG(RADEON_RBBM_SOFT_RESET); |
||
280 | OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset & |
||
281 | ~(RADEON_SOFT_RESET_CP | |
||
282 | RADEON_SOFT_RESET_HI | |
||
283 | RADEON_SOFT_RESET_SE | |
||
284 | RADEON_SOFT_RESET_RE | |
||
285 | RADEON_SOFT_RESET_PP | |
||
286 | RADEON_SOFT_RESET_E2 | |
||
287 | RADEON_SOFT_RESET_RB))); |
||
288 | INREG(RADEON_RBBM_SOFT_RESET); |
||
289 | |||
290 | if (info->ChipFamily <= CHIP_FAMILY_RV410) { |
||
291 | OUTPLL(RADEON_MCLK_CNTL, mclk_cntl); |
||
292 | OUTREG(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index); |
||
293 | OUTREG(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset); |
||
294 | } |
||
295 | }; |
||
296 | |||
297 | #define RADEON_WAIT_UNTIL_IDLE() do { \ |
||
298 | OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 1 ) ); \ |
||
299 | OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \ |
||
300 | RADEON_WAIT_3D_IDLECLEAN | \ |
||
301 | RADEON_WAIT_HOST_IDLECLEAN) ); \ |
||
302 | } while (0) |
||
303 | |||
304 | #define R300_ZB_ZCACHE_CTLSTAT 0x4f18 |
||
305 | # define RADEON_RB3D_ZC_FLUSH (1 << 0) |
||
306 | # define RADEON_RB3D_ZC_FREE (1 << 2) |
||
307 | # define RADEON_RB3D_ZC_FLUSH_ALL 0x5 |
||
308 | # define RADEON_RB3D_ZC_BUSY (1 << 31) |
||
309 | # define R300_ZC_FLUSH (1 << 0) |
||
310 | # define R300_ZC_FREE (1 << 1) |
||
311 | # define R300_ZC_BUSY (1 << 31) |
||
312 | # define RADEON_RB3D_DC_FLUSH (3 << 0) |
||
313 | # define RADEON_RB3D_DC_FREE (3 << 2) |
||
314 | # define RADEON_RB3D_DC_FLUSH_ALL 0xf |
||
315 | # define RADEON_RB3D_DC_BUSY (1 << 31) |
||
316 | # define R300_RB3D_DC_FLUSH (2 << 0) |
||
317 | # define R300_RB3D_DC_FREE (2 << 2) |
||
318 | # |
||
319 | #define RADEON_PURGE_CACHE() do { \ |
||
320 | if ( rhd.ChipFamily <= CHIP_FAMILY_RV280) { \ |
||
321 | OUT_RING(CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 1)); \ |
||
322 | OUT_RING(RADEON_RB3D_DC_FLUSH | RADEON_RB3D_DC_FREE); \ |
||
323 | } else { \ |
||
324 | OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 1)); \ |
||
325 | OUT_RING(R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE ); \ |
||
326 | } \ |
||
327 | } while (0) |
||
328 | |||
329 | #define RADEON_FLUSH_ZCACHE() do { \ |
||
330 | if ( rhd.ChipFamily <= CHIP_FAMILY_RV280) { \ |
||
331 | OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 1 ) ); \ |
||
332 | OUT_RING( RADEON_RB3D_ZC_FLUSH ); \ |
||
333 | } else { \ |
||
334 | OUT_RING( CP_PACKET0( R300_ZB_ZCACHE_CTLSTAT, 1 ) ); \ |
||
335 | OUT_RING( R300_ZC_FLUSH ); \ |
||
336 | } \ |
||
337 | } while (0) |
||
338 | #define RADEON_PURGE_ZCACHE() do { \ |
||
339 | if (rhd.ChipFamily <= CHIP_FAMILY_RV280) { \ |
||
340 | OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 1)); \ |
||
341 | OUT_RING(RADEON_RB3D_ZC_FLUSH | RADEON_RB3D_ZC_FREE); \ |
||
342 | } else { \ |
||
343 | OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 1)); \ |
||
344 | OUT_RING(R300_ZC_FLUSH | R300_ZC_FREE); \ |
||
345 | } \ |
||
346 | } while (0) |
||
347 | |||
348 | static int radeon_cp_start(RHDPtr info) |
||
349 | { |
||
350 | u32_t *ring, write; |
||
351 | u32_t ifl; |
||
352 | radeon_do_wait_for_idle(64); |
||
353 | |||
354 | OUTREG(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM); |
||
355 | |||
356 | ifl = safe_cli(); |
||
357 | |||
358 | BEGIN_RING(8); |
||
359 | /* isync can only be written through cp on r5xx write it here */ |
||
360 | OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 1)); |
||
361 | OUT_RING(RADEON_ISYNC_ANY2D_IDLE3D | |
||
362 | RADEON_ISYNC_ANY3D_IDLE2D | |
||
363 | RADEON_ISYNC_WAIT_IDLEGUI | |
||
364 | RADEON_ISYNC_CPSCRATCH_IDLEGUI); |
||
365 | RADEON_PURGE_CACHE(); |
||
366 | RADEON_PURGE_ZCACHE(); |
||
367 | RADEON_WAIT_UNTIL_IDLE(); |
||
368 | ADVANCE_RING(); |
||
369 | COMMIT_RING(); |
||
370 | |||
371 | safe_sti(ifl); |
||
372 | |||
373 | radeon_do_wait_for_idle(); |
||
374 | }; |
||
375 | |||
376 | |||
377 | Bool init_cp(RHDPtr info) |
||
378 | { |
||
379 | load_microcode(&rhd); |
||
380 | |||
381 | init_ring_buffer(&rhd); |
||
382 | |||
383 | radeon_engine_reset(&rhd); |
||
384 | |||
385 | /* setup the raster pipes */ |
||
386 | init_pipes(&rhd); |
||
387 | |||
388 | rhd.ring_rp = rhd.ring_wp = INREG(RADEON_CP_RB_RPTR); |
||
389 | OUTREG(RADEON_CP_RB_WPTR, rhd.ring_rp); |
||
390 | |||
391 | radeon_cp_start(&rhd); |
||
392 | |||
1002 | serge | 393 | return TRUE; |
883 | serge | 394 | };=>=>=>><>><>><>><>><>><>><>><>><>><>><>=>=>8)|13); |
395 | |||
396 |